Tải bản đầy đủ (.pdf) (829 trang)

Learning PHP, MySQL javascript

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (15.57 MB, 829 trang )

eb

Ap

on
iti
ile
Ed es ob
h ud M
5t I n c l p s &

W

Learning

PHP, MySQL,
& JavaScript
WITH JQUERY, CSS & HTML5

Robin Nixon



FIFTH EDITION

Learning PHP, MySQL & JavaScript
With jQuery, CSS & HTML5

Robin Nixon

Beijing



Boston Farnham Sebastopol

Tokyo


Learning PHP, MySQL & JavaScript
by Robin Nixon
Copyright © 2018 Robin Nixon. All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are
also available for most titles ( For more information, contact our corporate/insti‐
tutional sales department: 800-998-9938 or

Editor: Andy Oram
Production Editor: Melanie Yarbrough
Copyeditor: Rachel Head
Proofreader: Rachel Monaghan
July 2009:
August 2012:
June 2014:
December 2018:
May 2018:

Indexer: Judy McConville
Interior Designer: David Futato
Cover Designer: Karen Montgomery
Illustrator: Rebecca Demarest


First Edition
Second Edition
Third Edition
Fourth Edition
Fifth Edition

Revision History for the Fifth Edition
2018-05-08:

First Release

See for release details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Learning PHP, MySQL & JavaScript, the
cover image, and related trade dress are trademarks of O’Reilly Media, Inc.
While the publisher and the author have used good faith efforts to ensure that the information and
instructions contained in this work are accurate, the publisher and the author disclaim all responsibility
for errors or omissions, including without limitation responsibility for damages resulting from the use of
or reliance on this work. Use of the information and instructions contained in this work is at your own
risk. If any code samples or other technology this work contains or describes is subject to open source
licenses or the intellectual property rights of others, it is your responsibility to ensure that your use
thereof complies with such licenses and/or rights.

978-1-491-97891-7
[M]


For Julie




Table of Contents

Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
1. Introduction to Dynamic Web Content. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
HTTP and HTML: Berners-Lee’s Basics
The Request/Response Procedure
The Benefits of PHP, MySQL, JavaScript, CSS, and HTML5
MariaDB: The MySQL Clone
Using PHP
Using MySQL
Using JavaScript
Using CSS
And Then There’s HTML5
The Apache Web Server
Handling Mobile Devices
About Open Source
Bringing It All Together
Questions

2
2
5
6
6
7
8
10
10
11
12

12
13
14

2. Setting Up a Development Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
What Is a WAMP, MAMP, or LAMP?
Installing AMPPS on Windows
Testing the Installation
Accessing the Document Root (Windows)
Alternative WAMPs
Installing AMPPS on macOS
Accessing the Document Root (macOS)
Installing a LAMP on Linux
Working Remotely

18
18
22
24
25
26
27
28
28
v


Logging In
Using FTP
Using a Program Editor

Using an IDE
Questions

29
29
30
31
33

3. Introduction to PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Incorporating PHP Within HTML
This Book’s Examples
The Structure of PHP
Using Comments
Basic Syntax
Variables
Operators
Variable Assignment
Multiple-Line Commands
Variable Typing
Constants
Predefined Constants
The Difference Between the echo and print Commands
Functions
Variable Scope
Questions

35
37
38

38
39
40
45
48
50
52
53
54
55
55
56
62

4. Expressions and Control Flow in PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Expressions
TRUE or FALSE?
Literals and Variables
Operators
Operator Precedence
Associativity
Relational Operators
Conditionals
The if Statement
The else Statement
The elseif Statement
The switch Statement
The ? Operator
Looping
while Loops

do...while Loops
for Loops

vi

|

Table of Contents

63
64
65
66
67
69
70
74
75
76
78
79
82
83
84
86
86


Breaking Out of a Loop
The continue Statement

Implicit and Explicit Casting
PHP Dynamic Linking
Dynamic Linking in Action
Questions

88
89
90
91
92
93

5. PHP Functions and Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
PHP Functions
Defining a Function
Returning a Value
Returning an Array
Passing Arguments by Reference
Returning Global Variables
Recap of Variable Scope
Including and Requiring Files
The include Statement
Using include_once
Using require and require_once
PHP Version Compatibility
PHP Objects
Terminology
Declaring a Class
Creating an Object
Accessing Objects

Cloning Objects
Constructors
Destructors
Writing Methods
Declaring Properties
Declaring Constants
Property and Method Scope
Static Methods
Static Properties
Inheritance
Questions

96
97
98
99
100
102
102
103
103
103
104
104
105
106
107
108
108
110

111
111
112
113
113
114
115
116
117
120

6. PHP Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Basic Access
Numerically Indexed Arrays
Associative Arrays
Assignment Using the array Keyword

123
123
125
126

Table of Contents

|

vii


The foreach...as Loop

Multidimensional Arrays
Using Array Functions
is_array
count
sort
shuffle
explode
extract
compact
reset
end
Questions

127
129
132
132
132
133
133
133
134
135
136
136
137

7. Practical PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Using printf
Precision Setting

String Padding
Using sprintf
Date and Time Functions
Date Constants
Using checkdate
File Handling
Checking Whether a File Exists
Creating a File
Reading from Files
Copying Files
Moving a File
Deleting a File
Updating Files
Locking Files for Multiple Accesses
Reading an Entire File
Uploading Files
System Calls
XHTML or HTML5?
Questions

139
140
142
143
143
146
146
147
147
147

149
150
150
151
151
153
154
155
161
162
163

8. Introduction to MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
MySQL Basics
Summary of Database Terms
Accessing MySQL via the Command Line
Starting the Command-Line Interface

viii

|

Table of Contents

165
166
166
167



Using the Command-Line Interface
MySQL Commands
Data Types
Indexes
Creating an Index
Querying a MySQL Database
Joining Tables Together
Using Logical Operators
MySQL Functions
Accessing MySQL via phpMyAdmin
Questions

171
172
177
187
187
193
203
205
206
206
207

9. Mastering MySQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Database Design
Primary Keys: The Keys to Relational Databases
Normalization
First Normal Form
Second Normal Form

Third Normal Form
When Not to Use Normalization
Relationships
One-to-One
One-to-Many
Many-to-Many
Databases and Anonymity
Transactions
Transaction Storage Engines
Using BEGIN
Using COMMIT
Using ROLLBACK
Using EXPLAIN
Backing Up and Restoring
Using mysqldump
Creating a Backup File
Restoring from a Backup File
Dumping Data in CSV Format
Planning Your Backups
Questions

209
210
211
212
214
216
218
219
219

220
221
222
223
223
224
225
225
226
227
227
229
231
231
232
232

10. Accessing MySQL Using PHP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Querying a MySQL Database with PHP
The Process

235
235

Table of Contents

|

ix



Creating a Login File
Connecting to a MySQL Database
A Practical Example
The $_POST Array
Deleting a Record
Displaying the Form
Querying the Database
Running the Program
Practical MySQL
Creating a Table
Describing a Table
Dropping a Table
Adding Data
Retrieving Data
Updating Data
Deleting Data
Using AUTO_INCREMENT
Performing Additional Queries
Preventing Hacking Attempts
Steps You Can Take
Using Placeholders
Preventing HTML Injection
Using mysqli Procedurally
Questions

236
237
243
246

247
247
248
249
250
251
251
252
253
254
255
255
256
257
258
259
260
263
264
266

11. Form Handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
Building Forms
Retrieving Submitted Data
Default Values
Input Types
Sanitizing Input
An Example Program
HTML5 Enhancements
The autocomplete Attribute

The autofocus Attribute
The placeholder Attribute
The required Attribute
Override Attributes
The width and height Attributes
The min and max Attributes
The step Attribute
The form Attribute

x

|

Table of Contents

267
269
270
271
278
280
283
283
283
283
284
284
284
284
284

285


The list Attribute
The color Input Type
The number and range Input Types
Date and Time Pickers
Questions

285
285
285
286
286

12. Cookies, Sessions, and Authentication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
Using Cookies in PHP
Setting a Cookie
Accessing a Cookie
Destroying a Cookie
HTTP Authentication
Storing Usernames and Passwords
An Example Program
Using Sessions
Starting a Session
Ending a Session
Setting a Timeout
Session Security
Questions


287
289
290
290
290
294
296
299
299
302
303
304
307

13. Exploring JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
JavaScript and HTML Text
Using Scripts Within a Document Head
Older and Nonstandard Browsers
Including JavaScript Files
Debugging JavaScript Errors
Using Comments
Semicolons
Variables
String Variables
Numeric Variables
Arrays
Operators
Arithmetic Operators
Assignment Operators
Comparison Operators

Logical Operators
Incrementing, Decrementing, and Shorthand Assignment
String Concatenation
Escape Characters
Variable Typing

310
311
311
312
313
314
314
314
315
315
316
316
317
317
318
318
318
318
319
319

Table of Contents

|


xi


Functions
Global Variables
Local Variables
The Document Object Model
Another Use for the $ Symbol
Using the DOM
About document.write
Using console.log
Using alert
Writing into Elements
Using document.write
Questions

321
321
321
322
324
325
326
326
326
326
327
327


14. Expressions and Control Flow in JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Expressions
Literals and Variables
Operators
Operator Precedence
Associativity
Relational Operators
The with Statement
Using onerror
Using try...catch
Conditionals
The if Statement
The else Statement
The switch Statement
The ? Operator
Looping
while Loops
do...while Loops
for Loops
Breaking Out of a Loop
The continue Statement
Explicit Casting
Questions

329
330
331
332
332
333

336
337
338
339
339
339
340
342
342
342
343
344
345
345
346
347

15. JavaScript Functions, Objects, and Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
JavaScript Functions
Defining a Function
Returning a Value
Returning an Array

xii

|

Table of Contents

349

349
351
353


JavaScript Objects
Declaring a Class
Creating an Object
Accessing Objects
The prototype Keyword
JavaScript Arrays
Numeric Arrays
Associative Arrays
Multidimensional Arrays
Using Array Methods
Questions

354
354
356
356
356
359
360
361
362
363
368

16. JavaScript and PHP Validation and Error Handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371

Validating User Input with JavaScript
The validate.html Document (Part 1)
The validate.html Document (Part 2)
Regular Expressions
Matching Through Metacharacters
Fuzzy Character Matching
Grouping Through Parentheses
Character Classes
Indicating a Range
Negation
Some More Complicated Examples
Summary of Metacharacters
General Modifiers
Using Regular Expressions in JavaScript
Using Regular Expressions in PHP
Redisplaying a Form After PHP Validation
Questions

371
372
374
377
378
378
379
380
380
380
381
383

385
385
386
387
393

17. Using Asynchronous Communication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
What Is Asynchronous Communication?
Using XMLHttpRequest
Your First Asynchronous Program
Using GET Instead of POST
Sending XML Requests
Using Frameworks for Asynchronous Communication
Questions

396
396
399
403
406
411
411

18. Introduction to CSS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
Importing a Stylesheet

414

Table of Contents


|

xiii


Importing CSS from Within HTML
Embedded Style Settings
Using IDs
Using Classes
Using Semicolons
CSS Rules
Multiple Assignments
Using Comments
Style Types
Default Styles
User Styles
External Stylesheets
Internal Styles
Inline Styles
CSS Selectors
The Type Selector
The Descendant Selector
The Child Selector
The ID Selector
The Class Selector
The Attribute Selector
The Universal Selector
Selecting by Group
The CSS Cascade
Stylesheet Creators

Stylesheet Methods
Stylesheet Selectors
The Difference Between div and span Elements
Measurements
Fonts and Typography
font-family
font-style
font-size
font-weight
Managing Text Styles
Decoration
Spacing
Alignment
Transformation
Indenting
CSS Colors
Short Color Strings

xiv

|

Table of Contents

414
415
415
415
416
416

416
417
418
418
418
419
419
420
420
420
420
421
422
423
424
424
425
425
426
426
427
429
431
433
433
434
434
435
435
435

436
436
436
436
437
438


Gradients
Positioning Elements
Absolute Positioning
Relative Positioning
Fixed Positioning
Pseudoclasses
Shorthand Rules
The Box Model and Layout
Setting Margins
Applying Borders
Adjusting Padding
Object Contents
Questions

438
440
440
440
441
443
445
446

446
448
449
451
451

19. Advanced CSS with CSS3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Attribute Selectors
Matching Parts of Strings
The box-sizing Property
CSS3 Backgrounds
The background-clip Property
The background-origin Property
The background-size Property
Using the auto Value
Multiple Backgrounds
CSS3 Borders
The border-color Property
The border-radius Property
Box Shadows
Element Overflow
Multicolumn Layout
Colors and Opacity
HSL Colors
HSLA Colors
RGB Colors
RGBA Colors
The opacity Property
Text Effects
The text-shadow Property

The text-overflow Property
The word-wrap Property
Web Fonts
Google Web Fonts

454
454
455
456
456
458
458
459
459
461
461
461
465
466
466
468
468
469
469
469
470
470
470
470
471

472
473

Table of Contents

|

xv


Transformations
3D Transformations
Transitions
Properties to Transition
Transition Duration
Transition Delay
Transition Timing
Shorthand Syntax
Questions

474
475
476
476
477
477
477
478
480


20. Accessing CSS from JavaScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
Revisiting the getElementById Function
The O function
The S Function
The C Function
Including the Functions
Accessing CSS Properties from JavaScript
Some Common Properties
Other Properties
Inline JavaScript
The this Keyword
Attaching Events to Objects in a Script
Attaching to Other Events
Adding New Elements
Removing Elements
Alternatives to Adding and Removing Elements
Using Interrupts
Using setTimeout
Canceling a Timeout
Using setInterval
Using Interrupts for Animation
Questions

481
481
482
483
484
484
485

486
488
488
489
490
491
492
493
494
494
495
495
497
499

21. Introduction to jQuery. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Why jQuery?
Including jQuery
Choosing the Right Version
Downloading
Using a Content Delivery Network
Customizing jQuery
jQuery Syntax
A Simple Example

xvi

|

Table of Contents


501
502
502
504
504
505
505
506


Avoiding Library Conflicts
Selectors
The css Method
The Element Selector
The ID Selector
The Class Selector
Combining Selectors
Handling Events
Waiting Until the Document Is Ready
Event Functions and Properties
The blur and focus Events
The this Keyword
The click and dblclick Events
The keypress Event
Considerate Programming
The mousemove Event
Other Mouse Events
Alternative Mouse Methods
The submit Event

Special Effects
Hiding and Showing
The toggle Method
Fading In and Out
Sliding Elements Up and Down
Animations
Stopping Animations
Manipulating the DOM
The Difference Between the text and html Methods
The val and attr Methods
Adding and Removing Elements
Dynamically Applying Classes
Modifying Dimensions
The width and height Methods
The innerWidth and innerHeight Methods
The outerWidth and OuterHeight Methods
DOM Traversal
Parent Elements
Child Elements
Sibling Elements
Selecting the Next and Previous Elements
Traversing jQuery Selections
The is Method

507
507
508
508
509
509

509
510
511
512
513
514
514
515
517
517
520
521
522
523
524
525
526
527
528
531
532
533
533
535
537
537
538
540
540
541

541
545
545
547
549
550

Table of Contents

|

xvii


Using jQuery Without Selectors
The $.each Method
The $.map Method
Using Asynchronous Communication
Using the POST Method
Using the GET Method
Plug-ins
jQuery User Interface
Other Plug-ins
Questions

552
552
553
554
554

555
555
556
556
556

22. Introduction to jQuery Mobile. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
Including jQuery Mobile
Getting Started
Linking Pages
Linking Synchronously
Linking Within a Multipage Document
Page Transitions
Styling Buttons
List Handling
Filterable Lists
List Dividers
What Next?
Questions

560
561
563
563
564
565
568
571
572
574

577
577

23. Introduction to HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
The Canvas
Geolocation
Audio and Video
Forms
Local Storage
Web Workers
Microdata
Questions

579
581
583
584
585
585
585
586

24. The HTML5 Canvas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
Creating and Accessing a Canvas
The toDataURL Function
Specifying an Image Type
The fillRect Method
The clearRect Method
The strokeRect Method


xviii

|

Table of Contents

587
589
591
591
591
592


Combining These Commands
The createLinearGradient Method
The addColorStop Method in Detail
The createRadialGradient Method
Using Patterns for Fills
Writing Text to the Canvas
The strokeText Method
The textBaseLine Property
The font Property
The textAlign Property
The fillText Method
The measureText Method
Drawing Lines
The lineWidth Property
The lineCap and lineJoin Properties
The miterLimit Property

Using Paths
The moveTo and lineTo Methods
The stroke Method
The rect Method
Filling Areas
The clip Method
The isPointInPath Method
Working with Curves
The arc Method
The arcTo Method
The quadraticCurveTo Method
The bezierCurveTo Method
Manipulating Images
The drawImage Method
Resizing an Image
Selecting an Image Area
Copying from a Canvas
Adding Shadows
Editing at the Pixel Level
The getImageData Method
The putImageData Method
The createImageData Method
Advanced Graphical Effects
The globalCompositeOperation Property
The globalAlpha Property
Transformations

592
593
595

596
598
600
600
601
601
601
602
603
603
604
604
606
606
607
607
608
608
610
613
614
614
617
618
619
620
620
621
621
623

623
625
625
628
628
629
629
632
632

Table of Contents

|

xix


The scale Method
The save and restore Methods
The rotate Method
The translate Method
The transform Method
The setTransform Method
Questions

633
634
634
635
636

638
639

25. HTML5 Audio and Video. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
About Codecs
The <audio> Element
Supporting Non-HTML5 Browsers
The <video> Element
The Video Codecs
Supporting Older Browsers
Questions

642
643
646
647
648
651
653

26. Other HTML5 Features. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
Geolocation and the GPS Service
Other Location Methods
Geolocation and HTML5
Local Storage
Using Local Storage
The localStorage Object
Web Workers
Drag and Drop
Cross-Document Messaging

Other HTML5 Tags
Questions

655
656
657
660
661
661
663
666
668
672
672

27. Bringing It All Together. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 675
Designing a Social Networking App
On the Website
functions.php
The Functions
header.php
setup.php
index.php
signup.php
Checking for Username Availability
Logging In
checkuser.php

xx


|

Table of Contents

676
676
676
677
679
682
683
684
685
685
688


login.php
profile.php
Adding the “About Me” Text
Adding a Profile Image
Processing the Image
Displaying the Current Profile
members.php
Viewing a User’s Profile
Adding and Dropping Friends
Listing All Members
friends.php
messages.php
logout.php

styles.css
javascript.js

689
691
692
692
692
693
696
696
697
697
700
703
706
708
710

A. Solutions to the Chapter Questions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
B. Online Resources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735
C. MySQL’s FULLTEXT Stopwords. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739
D. MySQL Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743
E. jQuery Selectors, Objects, and Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 753
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777

Table of Contents

|


xxi



Preface

The combination of PHP and MySQL is the most convenient approach to dynamic,
database-driven web design, holding its own in the face of challenges from integrated
frameworks—such as Ruby on Rails—that are harder to learn. Due to its open source
roots (unlike the competing Microsoft .NET Framework), it is free to implement and
is therefore an extremely popular option for web development.
Any would-be developer on a Unix/Linux or even a Windows/Apache platform will
need to master these technologies. And, combined with the partner technologies of
JavaScript, jQuery, CSS, and HTML5, you will be able to create websites of the caliber
of industry standards like Facebook, Twitter, and Gmail.

Audience
This book is for people who wish to learn how to create effective and dynamic web‐
sites. This may include webmasters or graphic designers who are already creating
static websites but wish to take their skills to the next level, as well as high school and
college students, recent graduates, and self-taught individuals.
In fact, anyone ready to learn the fundamentals behind responsive web design will
obtain a thorough grounding in the core technologies of PHP, MySQL, JavaScript,
CSS, and HTML5, and you’ll learn the basics of the jQuery and jQuery Mobile libra‐
ries, too.

Assumptions This Book Makes
This book assumes that you have a basic understanding of HTML and can at least put
together a simple, static website, but does not assume that you have any prior knowl‐
edge of PHP, MySQL, JavaScript, CSS, or HTML5—although if you do, your progress

through the book will be even quicker.

xxiii


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×