markdown:
## Trước khi bạn bắt đầu
### Về hướng dẫn này
Hướng dẫn này kết thúc ứng dụng tiến trình công việc đơn giản mà bạn đã bắt đầu trong phần đầu tiên của loạt bài này về học PHP. Bạn sẽ thêm xác thực HTTP, khả năng tạo luồng tài liệu từ một vị trí truy cập không là trang Web và xử lý ngoại lệ. Bạn cũng sẽ thiết lập một số các ứng dụng trong các đối tượng.
Nói chung, bạn sẽ thêm khả năng cho một người quản trị để phê duyệt một tập tin, làm cho nó sẵn sàng cho những người dùng. Các chủ đề sau sẽ được thảo luận:
- Việc cho phép và sử dụng xác thực HTTP dựa trên trình duyệt.
- Tạo luồng dữ liệu từ một tập tin.
- Tạo các lớp và các đối tượng.
- Sử dụng các phương thức và các đặc tính của đối tượng.
- Tạo và xử lý các ngoại lệ.
- Sử dụng các thuộc tính định danh của XML
- Xác nhận tính hợp lệ một tài liệu XML bằng cách sử dụng DTD (Định nghĩa kiểu tài liệu - Document Type Definition).
- Kiểm soát truy cập dữ liệu dựa trên các trang yêu cầu.
### Ai cần sử dụng hướng dẫn này?
Hướng dẫn này là Phần 3 của loạt bài ba phần được thiết kế để dạy cho bạn những điều cơ bản về lập trình trong PHP trong khi xây dựng một ứng dụng tiến trình công việc đơn giản. Hướng dẫn này dành cho các nhà phát triển, những người muốn tìm hiểu thêm về các chủ đề nâng cao, chẳng hạn như sử dụng PHP để lập trình hướng đối tượng. Hướng dẫn này cũng đề cập đến việc xác thực HTTP, tạo luồng, các lớp và các đối tượng và xử lý ngoại lệ, cũng như cung cấp cái nhìn khác về thao tác XML.
Hướng dẫn này giả định bạn đã có một sự hiểu biết với các khái niệm cơ bản về PHP,
chẳng hạn như cú pháp, xử lý biểu mẫu và truy cập một cơ sở dữ liệu. Bạn có thể nhận
được các thông tin mà bạn cần nhờ hướng dẫn "
[Học PHP, Phần
1](http://www.ibm.com/developerworks/vn/edu/os-phptut1/index.html)" và " [Học PHP, Phần 2](http://www.ibm.com/developerworks/vn/edu/os-phptut2/index.html)," xem phần [Tài nguyên](#resources).
### Các điều kiện cần có trước
Để làm theo mã ví dụ, bạn cần bảo đảm các công cụ sau đây được cài đặt và chạy thử:
**Máy chủ HTTP** -- Bạn có thể cài đặt PHP trên nhiều máy chủ HTTP như Apache và
Microsoft® IIS, và trên Windows®, Linux®, UNIX®, Mac OS X, và các
nền tảng khác. Nói chung, sự lựa chọn của bạn về máy chủ không quan trọng, nhưng
hướng dẫn này sẽ trình bày một số vấn đề cấu hình liên quan đến việc xác thực HTTP
bằng cách sử dụng Apache 2.x như là một ví dụ. Bạn có thể tải về máy chủ Apache HTTP
từ [Apache](http://httpd.apache.org/download.cgi). **PHP** -- Tất nhiên, bạn sẽ cần một bản phân phối của PHP. Cả hai phiên bản V4 và
V5 của PHP đang sử dụng tại thời điểm viết bài này, nhưng hướng dẫn này tập trung vào
phiên bản V5 do những cải tiến nâng cao của nó. Hãy tải [PHP](http://www.php.net/downloads.php). **Cơ sở dữ liệu** -- Một phần của dự án này liên quan đến việc lưu dữ liệu vào một
cơ sở dữ liệu, do đó tất nhiên bạn cũng sẽ cần một cơ sở dữ liệu. Hướng dẫn này trình
bày cơ sở dữ liệu MySQL vì nó thường được dùng với PHP. Bạn có thể tải MySQL từ [http://dev.mysql.com/downloads/index.html](http://dev.mysql.com/downloads/index.html).
## Câu chuyện cho đến nay
### Bây giờ mọi thứ đã được đặt đúng chỗ
Bạn đã xây dựng một ứng dụng tiến trình công việc đơn giản thông qua diễn biến của các hướng dẫn này. Ứng dụng này cho phép người dùng tải các tập tin lên hệ thống và xem các tập tin đó, cũng như các tập tin đã được một quản trị viên hệ thống phê duyệt. Cho đến nay, bạn đã xây dựng:
- Một trang đăng ký cho phép người dùng sử dụng một biểu mẫu HTML để đăng ký tài khoản bằng cách nhập vào một tên người dùng duy nhất, địa chỉ e-mail và mật khẩu. Bạn đã xây dựng trang PHP để phân tích các dữ liệu được đệ trình, kiểm tra cơ sở dữ liệu để đảm bảo rằng tên người dùng là duy nhất và lưu đăng ký trong cơ sở dữ liệu.
- Một trang đăng nhập nhận tên và mật khẩu người dùng, kiểm tra chúng so với cơ sở dữ liệu và, nếu chúng được xác nhận hợp lệ, tạo một phiên làm việc trên máy chủ để máy chủ biết tập tin nào cần hiển thị.
- Các thành phần giao diện đơn giản cho phép phát hiện người dùng được đăng nhập chưa để hiển thị các lựa chọn thích hợp.
- Một trang tải lên cho phép người dùng gửi một tập tin đến máy chủ thông qua trình duyệt. Bạn cũng xây dựng trang để lấy tập tin tải lên và lưu nó vào máy chủ, sau đó thêm thông tin về nó vào một tập tin XML để phục hồi sau này, bằng cách sử dụng DOM (Mô hình đối tượng tài liệu).
- Một hàm hiển thị cho phép đọc tập tin XML và hiển thị thông tin nhờ API đơn giản với XML (SAX).
Bạn có thể tải các tập tin biểu thị nơi ứng dụng ngừng lại trong "
[Học PHP,
Phần 2](http://www.ibm.com/developerworks/vn/edu/os-phptut2/index.html)."
### Bạn sẽ làm gì
Trước khi bạn đi qua hướng dẫn này, bạn sẽ có -- tất nhiên, dù rất đơn giản -- một ứng dụng tiến trình công việc đầy đủ. Trong hướng dẫn này, bạn sẽ:
- Thêm xác thực HTTP, được máy chủ Web kiểm soát. Bạn cũng sẽ tích hợp quá trình đăng ký của bạn để nó thêm người dùng mới vào máy chủ Web.
- Thêm các liên kết đến hàm hiển thị các tập tin có sẵn để những người dùng có thể tải chúng. Bạn sẽ tạo một hàm cho phép tạo luồng cho các tập tin này tới trình duyệt từ vị trí truy cập không là trang Web.
- Xác nhận rằng những người sử dụng tải các tập tin từ trang thích hợp. Bạn sẽ sử dụng thực tế là các tập tin phải được ứng dụng tạo luồng, thay vì chỉ cần máy chủ HTTP phục vụ, cho phép kiểm soát các trường hợp trong đó những người sử dụng tải các tập tin
- Tạo một lớp thể hiện một tài liệu và sử dụng các phương thức hướng đối tượng để truy cập và tải nó.
- Tạo và sử dụng các ngoại lệ tùy chỉnh để trợ giúp các vấn đề cần chính xác.
- Thêm thông tin vào tập tin XML sẽ cho phép bạn là người duy nhất nhận biết mỗi tập tin. Bước này sẽ cho phép bạn thêm các hộp kiểm tra vào biểu mẫu hiển thị cho phép những người quản trị hệ thống có thể sử dụng để xác định duyệt các tập tin nào.
- Quản lý tiến trình phê duyệt, điều chỉnh tập tin XML của bạn để bạn có thể yêu
cầu trực tiếp các phần tử
fileInfocụ thể.
Hãy bắt đầu bằng cách thay đổi dáng vẻ chung về những gì bạn đã có.
### Trang chào mừng
Đến nay, bạn đã tập trung xây dựng các mẩu ứng dụng riêng của bạn. Bây giờ là lúc để
bắt đầu kết hợp chúng lại với nhau, do đó hãy bắt đầu với trang chào mừng đơn giản mà
bạn có thể sử dụng như một "dải hạ cánh" cho những người truy cập. Tạo một tập tin
mới gọi là
*index.php* và thêm vào:
<?php include ("top.txt"); include ("scripts.txt"); display_files(); include ("bottom.txt"); ?>
Hàm
include() đầu tiên nạp các thành phần giao diện trên
cùng cho trang đó và thiết lập một phiên làm việc, nếu thích hợp. Hàm include () thứ
hai nạp tất cả các kịch bản lệnh mà bạn đã tạo cho đến nay, bao gồm hàm
display_files() mà bạn đã tạo trong "
[Học PHP,
Phần 2](http://www.ibm.com/developerworks/vn/edu/os-phptut2/index.html)," đã liệt kê tất cả các tập tin được người dùng hiện tại tải lên hoặc
đã được người quản trị phê duyệt. Hàm include cuối cùng chỉ là phần dưới cùng của
trang HTML.
Lưu tập tin này trong cùng thư mục với các tập tin khác bạn đã tạo ra. Ví dụ, bạn có thể đặt tập tin đó trong thư mục gốc tài liệu của máy chủ của bạn, do đó một khi bạn đã khởi động máy chủ HTTP, bạn có thể xem trang đó bằng cách trỏ trình duyệt của bạn đến http://localhost/index.php.
Như bạn thấy trong Hình 1, trang này khá đơn giản và, trên thực tế nếu bạn đã tiếp
tục đi, bạn không nên xem
*bất kỳ* các tập tin nào, trừ khi bạn đã đăng nhập vì
chưa gì được phê duyệt cả. Các tập tin ở đây đã được phê duyệt cho mục đích trình
diễn.
##### Hình 1. Trang liệt kê cơ bản
![ Trang liệt kê cơ bản](phppart3fig1.jpg)
Nếu bạn chỉ mới khởi động trình duyệt của bạn, bạn sẽ thấy các liên kết
**Register** và **Login** vì bạn chưa đăng nhập. Trong phần tiếp theo, bạn
sẽ xem một cách khác để xử lý quá trình đó.
## Sử dụng xác thực HTTP
### Xác thực HTTP
Cho đến nay, bạn đã sử dụng hệ thống đăng nhập trong đó người dùng nhập tên và mật
khẩu vào một biểu mẫu và khi họ đệ trình biểu mẫu, thông tin đó được kiểm tra so với
cơ sở dữ liệu MySQL. Nếu nó phù hợp, ứng dụng này tạo một phiên làm việc trong PHP và
gán một tên người dùng cho mảng
$_SESSION để sử dụng sau
này.
Trong khi tiến trình này làm việc tốt, bạn gặp một vấn đề khi bạn tích hợp với các hệ
thống khác. Ví dụ, nếu ứng dụng tiến trình công việc của bạn đã là một phần của một
mạng nội bộ trong đó những người dùng có thể đăng nhập với các tên người dùng từ các
hệ thống khác, bạn có thể không muốn yêu cầu họ đăng nhập lại. Thay vào đó, bạn muốn
họ đã được đăng nhập rồi khi đã ở trong mạng, nếu họ đã đăng nhập ở nơi khác. Điều
này được gọi là hệ thống
*đăng nhập một lần*.
Để thực hiện điều đó ở đây, bạn sẽ chuyển sang một hệ thống có máy chủ Web thực sự kiểm soát quá trình đăng nhập. Thay vì chỉ đơn giản dùng trang này, máy chủ kiểm tra tên người dùng và mật khẩu trong lúc có yêu cầu từ trình duyệt và nếu máy chủ không thấy chúng, máy chủ lệnh cho trình duyệt bật lên một hộp thoại tên người dùng và mật khẩu để bạn có thể nhập thông tin. Một khi nhập thông tin, bạn sẽ không phải thực hiện nó lại vì trình duyệt sẽ gửi nó cùng với các yêu cầu tiếp theo.
Hãy bắt đầu bằng cách thiết lập máy chủ.
### Kích hoạt xác thực HTTP
Trước khi bắt đầu, bạn hãy lưu ý nếu sử dụng máy chủ khác Apache 2.x, bạn nên kiểm tra tài liệu về xác thực HTTP để xem bạn cần làm gì để thiết lập nó. (Hoặc là bạn có thể đơn giản bỏ qua phần này. Bạn sẽ có sẵn các bước thích hợp để cho ứng dụng làm việc với bất kì kiểu xác thực nào).
Nhưng việc xác thực HTTP thực sự làm việc ra sao? Trước hết, máy chủ biết nó cần loại bảo mật nào để cung cấp cho mỗi thư mục. Một cách thay đổi điều đó với một thư mục cụ thể là thiết lập các thứ trong cấu hình chính cho máy chủ. Một cách khác là sử dụng một tập tin .htaccess, có chứa các hướng dẫn với thư mục có tập tin đó.
Ví dụ, bạn muốn máy chủ đảm bảo rằng tất cả những người dùng truy cập các tập tin cho
riêng người dùng của bạn có các tên người dùng và các mật khẩu hợp lệ, do đó trước
tiên tạo một thư mục gọi là
*loggedin* bên trong thư mục có chứa tập tin hiện
tại của bạn. Ví dụ, nếu tập tin của bạn nằm trong /usr/local/apache2/htdocs, bạn sẽ
tạo thư mục /usr/local/apache2/htdocs/loggedin.
Bây giờ bạn cần báo cho máy chủ biết rằng bạn sắp phủ lên an ninh tổng thể với thư mục đó, do đó hãy mở tập tin:
<Directory /usr/local/apache2/htdocs/loggedin> AllowOverride AuthConfig </Directory>
(Tất nhiên, bạn nên sử dụng thư mục đúng cho thiết lập riêng của mình).
Bây giờ là lúc chuẩn bị thư mục thực sự.
### Thiết lập việc xác thực
Tiếp theo, tạo một tập tin văn bản mới và lưu tập tin đó trong thư mục loggedin với tên là .htaccess. Thêm vào đó:
AuthName "Registered Users Only" AuthType Basic AuthUserFile /usr/local/apache2/password/.htpasswd Require valid-user
Chúng ta hãy thực hiện điều này từ đầu.
AuthName là văn
bản xuất hiện ở đầu của hộp thoại tên người dùng và mật khẩu
AuthType xác định bạn đang sử dụng xác thực kiểu
Basic, có nghĩa bạn sẽ gửi tên người dùng và mật khẩu theo dạng văn bản
rõ.
AuthUserFile là tập tin chứa các tên đăng nhập và các
mật khẩu cho phép. (Bạn sẽ tạo tập tin đó ngay). Cuối cùng, chỉ dẫn
Require để cho bạn xác định người thực sự xem nội dung này. Ở
đây, bạn sẽ nói rằng bạn sẽ hiển thị nó cho bất kỳ người dùng hợp lệ nào, nhưng bạn
cũng có tùy chọn để quy định những người dùng hoặc nhóm người dùng cụ thể.
Khởi động lại máy chủ HTTP để những thay đổi này có hiệu lực.
(Đối với Apache V2.0, gọi
<APACHE_HOME>/bin/apachectl
stop, tiếp theo là
<APACHE_HOME>/bin/apachectl
start.)
Tiếp theo, bạn sẽ tạo tập tin mật khẩu.
### Tạo tập tin mật khẩu
Để tất cả điều này hoạt động, bạn cần có tập tin mật khẩu để máy chủ có thể kiểm tra
nó. Trong phần
[Thêm những người dùng mới vào](#addnewuser), vào tập tin
mật khẩu, bạn sẽ xem xét thao tác tập tin này từ bên trong PHP, nhưng bây giờ, nếu
bạn có quyền truy cập vào dòng lệnh, bạn có thể trực tiếp tạo tập tin đó.
Trước tiên, chọn một vị trí cho tập tin .htpasswd của bạn. Tập tin đó
*không có*
trong thư mục có thể truy cập trang Web. Tập tin đó cũng không thật an toàn khi có ai
đó chỉ cần tải về và phân tích nó. Tập tin đó cũng phải ở tại nơi mà PHP có thể viết
vào nó. Ví dụ, bạn có thể tạo một thư mục mật khẩu trong thư mục apache2 của bạn. Bất
kể bạn chọn vị trí nào, hãy đảm bảo bạn có thông tin chính xác trong tập tin
.htaccess của bạn.
Để tạo tập tin mật khẩu, hãy thực hiện lệnh sau, thay thế thư mục và tên người dùng riêng của bạn:
htpasswd -c /usr/local/apache2/password/.htpasswd roadnick
Sau đó bạn được nhắc gõ vào, rồi lặp lại mật khẩu, như sau:
htpasswd -c /usr/local/apache2/password/.htpasswd roadnick New password: Re-type new password: Adding password for user roadnick
Khóa chuyển đổi
-c lệnh cho máy chủ biết để tạo một tập
tin mới, vì thế sau khi bạn đã thêm người dùng mới, tập tin đó sẽ trông giống như
sau:
roadnick:IpoRzCGnsQv.Y
Lưu ý rằng phiên bản này của mật khẩu được mã hóa và bạn phải nhớ nó khi thêm các mật khẩu từ ứng dụng của bạn.
Bây giờ hãy xem phiên bản này hoạt động.
### Đăng nhập
Để xem phiên bản này hoạt động, bạn cần truy cập một tập tin trong thư mục được bảo vệ. Chuyển các tập tin uploadfile.php và uploadfile_action.php vào thư mục loggedin và sao chép index.php vào thư mục loggedin như là display_files.php.
Trong mỗi một trong ba tập tin trên, hãy thay đổi các câu lệnh
include() thành tài khoản cho vị trí mới, như sau:
<?php include ("
../top.txt"); include (" ../scripts.txt"); echo "Logged in user is ".$_SERVER['PHP_AUTH_USER'];display_files(); include (" ../bottom.txt"); ?>
Trong trường hợp này, bạn sửa chữa các tham chiếu tới các tập tin kèm theo, nhưng bạn cũng tham chiếu một biến cần được thiết lập khi trình duyệt gửi tên người dùng và mật khẩu. Trỏ trình duyệt của bạn tới http://localhost/loggedin/display_files.php để xem việc này hoạt động. Như bạn thấy trong Hình 2, bạn sẽ nhận được một hộp thoại tên người dùng và mật khẩu.
##### Hình 2. Hộp thoại tên đăng nhập và mật khẩu
![ Hộp thoại tên đăng nhập và mật khẩu](phppart3fig2.jpg)
Nhập tên người dùng và mật khẩu mà bạn thường dùng trong phần Tạo tập tin mật khẩu để xem trang thực tế.
### Sử dụng thông tin đăng nhập
Tại thời điểm này, bạn đã nhập tên người dùng và đăng nhập, vì thế bạn có thể xem
trang đó. Tuy nhiên, như bạn có thể thấy trong Hình 3, mặc dù thông báo cho biết
người sử dụng đã đăng nhập, nhưng nội dung thực sự có vẻ không đúng. Bạn vẫn thấy các
liên kết
**Register** (Đăng ký) và **Login** (Đăng nhập), và danh sách các tập
tin vẫn còn hiển thị chỉ những tập tin mà người quản trị hệ thống đã phê duyệt -- chứ
không phải những tập tin mà người dùng hiện tại đã tải lên và vẫn đang chờ giải
quyết.
##### Hình 3. Loại Logged in ...
![ Loại Logged in ...](phppart3fig3.jpg)
Để giải quyết những vấn đề này, bạn có hai lựa chọn. Thứ nhất là quay trở lại và mã
hóa lại mọi trường hợp trong đó ứng dụng tham chiếu tên người dùng để tìm
$_SERVER['PHP_AUTH_USER'], thay cho
$_SESSION["username"]. Tuy nhiên, những lập trình viên giỏi vốn lười
biếng, vì thế đây không là tùy chọn đặc biệt hấp dẫn.
Sự lựa chọn thứ hai là chỉ cần thiết lập
$_SESSION["username"] dựa vào
$_SERVER['PHP_AUTH_USER'] để mọi thứ sẽ tiếp tục làm việc như đã làm trước
đây. Bạn có thể làm điều này trong tập tin top.txt, ngay sau khi bạn bắt đầu một
phiên làm việc mới hoặc kết nối vào một phiên làm việc hiện có:
<? session_start();
if (isset($_SESSION["username"])){ //Do nothing } elseif (isset($_SERVER['PHP_AUTH_USER'])) { $_SESSION["username"] = $_SERVER['PHP_AUTH_USER']; }?>   <title>Workflow System</title>
Trước hết, cách duy nhất để làm cho trình duyệt "quên" tên người dùng và mật khẩu bạn
đã nhập là đóng trình duyệt đó lại để bạn đưa ra quyền ưu tiên của biến
$_SESSION["username"]. Bằng cách đó, bạn có tùy chọn để cho
phép những người dùng đăng nhập như là người khác. (Bạn sẽ không làm điều đó ở đây,
nhưng bạn có tùy chọn đó).
Tiếp theo, nếu chưa thiết lập cả biến
$_SESSION lẫn biến
$_SERVER, thì không có điều gì xảy ra và trang đó vẫn
tiếp tục như thể người dùng không đăng nhập -- điều xảy ra là một trường hợp. Việc
làm cho trường hợp này thành một thay đổi đơn giản sẽ sửa chữa vấn đề đăng nhập của
bạn, như bạn có thể thấy trong Hình 4.
##### Hình 4. Trang đã sửa chữa
![ Trang đã sửa chữa](phppart3fig4.jpg)
### Thay đổi giao diện
Trước khi bạn tiếp tục thêm một người dùng mới, bạn cần thực hiện một số thay đổi
nhanh chóng cho tập tin top.txt để điều chỉnh cấu trúc mới. Trước hết, bạn cần thay
đổi liên kết
**Login** để thay vì trỏ vào trang login.php cũ của bạn, nó trỏ đến
tập tin display_files.php vừa mới được bảo mật. Khi người dùng cố gắng truy cập tập
tin đó, trình duyệt sẽ cung cấp một cách để đăng nhập:
...

Navigation
 <?php if (isset($_SESSION["username"]) || isset($username)){ ?>
You are logged in as
<?=$_SESSION["username"].$username?>.

Upload a file

Display files
 <?php } else { ?>
Register

Login
 <?php } ?>
Lưu ý rằng ngoài việc thay đổi tham chiếu đăng nhập và thêm một tùy chọn mới để hiển thị danh sách các tập tin, chúng tôi đã giải thích qua thông báo về đăng xuất, do chủ đề đó vượt quá phạm vi của hướng dẫn này.
Bây giờ bạn chỉ cần tích hợp quá trình đăng ký với tập tin mật khẩu.
### Thêm những người dùng mới vào tập tin mật khẩu
Bước cuối cùng trong quá trình này là tích hợp đăng ký của bạn với tập tin .htpasswd. Để làm điều đó, bạn chỉ cần thêm một mục mới ngay khi bạn đã lưu người sử dụng đó vào cơ sở dữ liệu. Mở tập tin registration_action.php và thêm vào như sau:
... $passwords = $_POST["pword"]; $sql = "insert into users (username, email, password) values ('" .$_POST["name"]."', '".$_POST["email"] ."', '".$passwords[0]."')"; $result = mysql_query($sql); if ($result){ echo "It's entered!";
$pwdfile = '/usr/local/apache2/password/.htpasswd'; if (is_file($pwdfile)){ $opencode = "a"; } else { $opencode = "w"; } $fp = fopen($pwdfile, $opencode); $pword_crypt = crypt($passwords[0]); fwrite($fp, $_POST['name'].":".$pword_crypt."\n"); fclose($fp);} else { echo "There's been a problem: ".mysql_error(); } } else { echo "There is already a user with that name. Please try again.
"; ...
Trước khi bạn bắt đầu, nếu bạn đã có một tập tin .htpasswd rồi, hãy đảm bảo rằng người dùng có thể viết vào tập tin đó trên máy chủ Web của bạn. Nếu không, hãy chắc chắn rằng người dùng có thể viết vào thư mục thích hợp.
Trước hết, hãy kiểm tra xem tập tin đó có tồn tại không và sử dụng thông tin đó để xác định xem bạn sẽ viết một tập tin mới hoặc nối thêm thông tin vào một tập tin hiện có không. Một khi bạn biết rồi, hãy tiếp tục và mở tập tin đó.
Như bạn đã thấy trong phần Tạo tập tin mật khẩu, mật khẩu này được lưu giữ dưới dạng
đã mã hóa, vì vậy bạn có thể sử dụng hàm
crypt() để nhận
được chuỗi đó. Cuối cùng, viết tên người dùng và mật khẩu vào tập tin đó và đóng tập
tin lại.
Để kiểm tra điều này, hãy thoát khỏi trình duyệt để xóa bất kỳ mật khẩu được nhớ nhanh nào, rồi mở http://localhost/index.php.
Nhấn vào
**Register** và tạo một tài khoản mới. Khi bạn đã hoàn thành việc tạo tài
khoản, thoát khỏi trình duyệt một lần nữa và thử truy cập vào một trang được bảo vệ.
Tên đăng nhập và mật khẩu mới sẽ làm việc.
## Sử dụng các luồng
### Các luồng là gì?
Bây giờ bạn đã có hệ thống được thiết lập, bạn đã sẵn sàng để cho phép người dùng thực sự tải về các tập tin có sẵn. Tuy nhiên, ngay từ đầu, những tập tin này đã được lưu trữ trong một thư mục có thể truy cập được không phải trang Web, vì vậy một liên kết đơn giản tới các tập tin đó vượt ra ngoài điều đang bàn đến.
Thay vào đó, trong phần này, bạn sẽ tạo ra một hàm để tạo luồng cho tập tin từ vị trí hiện tại của nó tới trình duyệt.
Bây giờ, cách bạn thực sự truy cập nguồn tài nguyên, chẳng hạn như một tập tin, tùy thuộc vào nơi và cách thức lưu tập tin. Việc truy cập vào một tập tin vị trí là rất khác với việc truy cập vào tập tin trên một máy chủ ở xa thông qua HTTP hoặc FTP.
Tuy nhiên, may mắn thay, PHP cung cấp
*các trình bao bọc luồng * (stream
wrappers). Nói cách khác, bạn thực hiện một cuộc gọi đến một tài nguyên, bất cứ nơi
nào nó có và nếu PHP có một trình bao bọc (wrapper) có hiệu lực, PHP sẽ tìm ra cách
để thực hiện cuộc gọi đó.
Bạn có thể tìm các trình bao bọc có sẵn bằng cách in các nội dung của mảng được hàm
stream_get_wrappers() trả về, giống như sau:
<?php print_r(stream_get_wrappers()); ?>
Hàm
print_r() rất dễ sử dụng để xem các nội dung của một
mảng. Ví dụ, hệ thống của bạn có thể cung cấp cho bạn:
Array ( [0] => php [1] => file [2] => http [3] => ftp )
Điều này sẽ cho phép bạn dễ dàng lưu trữ các tập tin của bạn trên một máy chủ Web hoặc máy chủ FTP ở xa như là một sự thay thế cho việc lưu trữ chúng như là các tập tin trên máy chủ nội bộ và mã được bạn sử dụng trong phần này sẽ vẫn làm việc.
Chúng ta hãy xem xét.
### Tải tập tin
Đối với người dùng để có thể xem một tập tin, trình duyệt phải thu nhận nó. Trình
duyệt cũng phải biết tập tin nào để hiển thị nó đúng. Bạn có thể quan tâm đến cả hai
vấn đề này. Hãy tạo một tập tin mới gọi là
*download_file.php* và lưu nó trong
thư mục loggedin. Thêm vào như sau:
<?php include ("../scripts.txt"); $filetype = $_GET['filetype']; $filename = $_GET['file']; $filepath = UPLOADEDFILES.$filename; if($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$filetype); print($file_contents); } ?>
Không kể sức mạnh của nó, ở đây quá trình này trong thực tế là khá đơn giản. Trước
tiên, bạn mở tập tin để đọc và để đưa vào bộ đệm. Điều bạn đang thực sự làm với hàm
fopen() sẽ tạo ra một nguồn tài nguyên biểu thị tập tin
đó. Sau đó bạn có thể chuyển tài nguyên đó tới hàm
stream_get_contents(), để đọc toàn bộ tập tin ra thành một chuỗi đơn.
Bây giờ bạn có nội dung, bạn có thể gửi nó vào trình duyệt, nhưng trình duyệt sẽ
không biết phải làm gì với nội dung đó và có khả năng sẽ hiển thị nó dưới dạng văn
bản. Điều đó là tốt cho một tập tin văn bản, nhưng không tốt cho một tập tin ảnh hoặc
thậm chí một tập tin HTML. Vì vậy, thay vì chỉ gửi đi nội dung thô, trước tiên bạn
gửi một
header (tiêu đề) cho trình duyệt với thông tin về
Content-type (kiểu-nội dung) của tập tin, chẳng hạn như
image/jpeg.
Cuối cùng, bạn chỉ đơn giản xuất ra các nội dung của tập tin cho trình duyệt. Khi đã
nhận phần tiêu đề
Content-type, trình duyệt sẽ biết để
không chỉ xử lý nó như là một trang Web (tất nhiên, trừ khi nó
*là* một trang
Web).
Cho đến lúc quyết định thực sự sử dụng tập tin nào và kiểu nào, bạn sẽ đọc chúng từ
mảng
$_GET, vì vậy bạn có thể thêm chúng ngay vào URL, như
sau:
http://localhost/loggedin/download_file.php
?file=timeone.jpg&filetype=image/jpeg
Nhập URL này (tất nhiên với một tên tập tin và kiểu thích hợp) vào trình duyệt của bạn để xem kết quả được hiển thị trong Hình 5.
##### Hình 5. Tải một tập tin
![ Tải một tập tin](phppart3fig5.jpg)
### Thêm một liên kết đến tập tin
Bởi vì tất cả các thông tin mà trang tải xuống cần có thể được thêm vào URL, thật đơn
giản để thêm một liên kết cho phép người dùng tải về một tập tin. Bạn tạo sự hiển thị
các tập tin có sẵn bằng cách sử dụng một luồng SAX, có nghĩa là kết quả đầu ra thực
tế được kiểm soát bởi một lớp của trình xử lý nội dung được gọi, trong trường hợp
này, là
Content_Handler. Mở tập tin scripts.txt và thêm mã
sau vào lớp
Content_Handler:
class Content_Handler{ private $available = false; private $submittedBy = ""; private $status = ""; private $currentElement = ""; private $fileName = ""; private $fileSize = "";
private $fileType = "";function start_element($parser, $name, $attrs){ ... } function end_element($parser, $name){ if ($name == "workflow"){ echo "
"; } if ($name == "fileInfo"){ echo "
 fileName." &filetype=".$this->fileType."'>" .$this->fileName." 	"." ".$this->submittedBy."	"." ".$this->fileSize."	"." ".$this->status."
"; $this->fileName = ""; $this->submittedBy = ""; $this->fileSize = ""; $this->status = ""; $this->fileType = "";$this->available = false; } $this->currentElement = ""; } function chars($parser, $chars){ if ($this->available){ if ($this->currentElement == "fileName"){ $this->fileName = $this->fileName . $chars; } if ($this->currentElement == "fileType"){ $this->fileType = $this->fileType . $chars; }if ($this->currentElement == "size"){ $this->fileSize = $this->fileSize .$chars; } } } }
Ngoài những thông tin mà bạn đã theo dõi với mỗi phần tử
fileInfo, bây giờ bạn cần phải theo dõi phần tử
fileType, vì vậy bạn cần phải thêm một đặc tính cho phần tử đó.
Với hàm
chars(), bạn lưu giá trị khi bạn bắt đầu nó. Khi
bạn đi tới cuối phần tử
fileInfo và đó là lúc để hiển thị
các thông tin, bạn sử dụng hàm đó, cùng với
fileName (tên
tập tin), để tạo ra một liên kết trỏ đến trang tải xuống. Bạn có thể xem kết quả
trong Hình 6.
##### Hình 6. Liên kết đến tập tin
![ Liên kết đến tập tin](phppart3fig6.jpg)
Nhấn vào một liên kết để kiểm tra tập tin.
Tiếp theo, bạn sẽ xem xét việc đóng gói quá trình này thành một đối tượng.
## Sử dụng các đối tượng
### Vậy các đối tượng là gì?
Trong phần này, bạn sẽ xem xét việc sử dụng
*các đối tượng*. Cho đến nay, hầu
như tất cả mọi thứ mà bạn đã làm đều *theo thủ tục*, có nghĩa là bạn có một kịch
bản lệnh hầu như chạy từ đầu đến cuối. Bây giờ bạn sẽ di chuyển ra khỏi đó.
Khái niệm trung tâm của lập trình hướng đối tượng là ý tưởng mà bạn có thể biểu thị "những thứ" như một gói độc lập. Ví dụ, một ấm điện có các đặc tính, chẳng hạn như màu sắc và nhiệt độ tối đa của nó và các khả năng, chẳng hạn như làm nóng nước và tự tắt.
Nếu bạn đã biểu thị rằng ấm đun nước như là một đối tượng, nó cũng sẽ có các đặc tính
như
color (màu sắc) và
maximumTemperature (nhiệt độ tối đa) và các khả năng -- hoặc
*các phương
thức* -- như
heatWater() (làm nóng nước) và
turnOff() (tự tắt). Nếu bạn đang viết một chương trình cho
phép giao tiếp với ấm đun nước, bạn chỉ cần gọi phương thức
heatWater() của đối tượng ấm đun nước, hơn là lo lắng về cách nó thực hiện
trong thực tế.
Để làm cho những điều này rõ hơn một chút, bạn sẽ tạo ra một đối tượng biểu thị một
tập tin được tải xuống. Nó sẽ có các đặc tính, chẳng hạn như tên gọi và kiểu tập tin
và các phương thức, chẳng hạn như
download().
Tuy nhiên, khi đã nói tất cả điều đó, chúng ta cần chỉ ra rằng bạn chưa thực sự định
nghĩa một đối tượng. Thay vào đó, bạn định nghĩa một
*lớp* của các đối tượng.
Một lớp hoạt động như một loại "khuôn mẫu" cho các đối tượng của kiểu đó. Sau đó bạn
tạo ra một *thể hiện* của lớp đó và biểu hiện đó là đối tượng.
Hãy bắt đầu bằng cách tạo ra lớp thực tế.
### Tạo lớp WFDocument
Bước đầu tiên trong việc xử lý các đối tượng là tạo lớp mà trên đó các đối tượng dựa vào. Bạn có thể thêm định nghĩa này vào tập tin scripts.txt, nhưng bạn đang cố gắng để tạo mã có khả năng duy trì được nhiều hơn, chứ không ít hơn. Vì vậy, tạo một tập tin riêng biệt, WFDocument.php và lưu nó trong thư mục chính. Thêm vào như sau:
<?php include_once("scripts.txt"); class WFDocument { function download($filename, $filetype) { $filepath = UPLOADEDFILES.$filename; if($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$filetype); print($file_contents); } } } ?>
Trước tiên, bạn cần hằng số
UPLOADEDFILES, vì vậy bạn bao
gồm tập tin scripts.txt. Tiếp theo, bạn tạo ra lớp thực tế. Lớp
WFDocument chỉ có một phương thức duy nhất là,
download(), giống như mã trong tập tin download_file.php, ngoại trừ việc
nhận tên và kiểu tập tin làm các đầu vào cho hàm đó hơn là trực tiếp trích xuất chúng
khỏi mảng
$_GET array.
Bây giờ hãy xem xét việc tạo lớp này
### Gọi đối tượng WFDocument-type
Bạn đã thực sự đã tạo một số đối tượng khi bạn đang làm việc với DOM trong
[Phần 2](http://www.ibm.com/developerworks/vn/edu/os-phptut2/index.html)
của loạt bài này, nhưng chúng tôi đã không nói nhiều về lý do tại sao hoặc như thế
nào. Chúng tôi sẽ khắc phục điều đó bây giờ.
Mở trang download_file.php và thay đổi mã để nó đọc như sau:
<?php include ("../
WFDocument.php"); $filetype = $_GET['filetype']; $filename = $_GET['file']; $wfdocument = new WFDocument(); $wfdocument->download($filename, $filetype);?>
Trước hết, thay vì bao gồm tập tin scripts.txt, bạn sẽ bao gồm định nghĩa của lớp
WFDocument mà bạn đưa vào tập tin WFDocument.php. (Một
số các nhà phát triển tìm thấy nó có ích để chỉ tạo một trang bao gồm tất cả các lớp
của họ, sau đó bao gồm trang đó chứ không phải bao gồm tất cả các lớp riêng biệt ở
khắp nơi).
Bây giờ bạn đã sẵn sàng để tạo ra một đối tượng mới, mà bạn làm bằng cách sử dụng từ
khoá
new (mới). Dòng này tạo một đối tượng mới theo kiểu
WFDocument và gán nó vào biến
$wfdocument.
Một khi bạn có một tham chiếu đến đối tượng đó, bạn có thể gọi bất kỳ phương thức
chung nào của nó. Trong trường hợp này, chỉ có một phương thức,
download(), và bạn gọi nó bằng cách sử dụng toán tử
->. Về cơ bản, biểu tượng này có nghĩa, "Sử dụng phương thức (hoặc đặc
tính) thuộc về đối tượng này".
Lưu tập tin và kiểm tra nó bằng cách nhấn vào một trong các liên kết trên trang của bạn. Mã giống hệt như nó đã có trước đó. Sự khác biệt duy nhất là cách bạn đang gọi nó.
### Tạo các đặc tính
Tất nhiên, các phương thức chỉ là một phần của câu chuyện. Phần bao trùm của một đối
tượng là nó được đóng gói. Nói cách khác, nó phải chứa tất cả thông tin riêng của
mình, vì thế thay vì cung cấp tên và loại tập tin cho phương thức
download(), bạn có thể đặt chúng như là các đặc tính về đối tượng. Nhưng
trước tiên bạn cần tạo chúng trong lớp đó:
<?php include_once("../scripts.txt"); class WFDocument {
public $filename; public $filetype;function download (){ $filepath = UPLOADEDFILES. $this->filename; if($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ". $this->filetype); print($file_contents); } } } ?>
Lưu ý rằng bạn khai báo các biến bên ngoài hàm; chúng là một phần của lớp và không
phải là hàm. Bạn cũng khai báo chúng là
public (chung), có
nghĩa là bạn có thể truy cập chúng từ chính bên ngoài lớp đó. Bạn cũng có thể thiết
lập một đặc tính là
private (riêng), có nghĩa là bạn có
thể sử dụng nó chỉ trong chính lớp đó hoặc
protected (được
bảo vệ), có nghĩa là bạn có thể sử dụng nó chỉ trong lớp đó hoặc bất kỳ các lớp nào
dựa vào đặc tính này. (Nếu bạn không quen với ý tưởng này, hãy kiên nhẫn chờ đợi một
lát. Chúng tôi sẽ nói thêm về khái niệm này,
*quyền thừa kế* (inheritance) ,
trong phần [Tạo một ngoại lệ tùy chỉnh](#inheritance).)
Cuối cùng, để tham khảo một đặc tính đối tượng, bạn phải biết đặc tính đó thuộc về
đối tượng nào. Trong bản thân đối tượng, bạn có thể chỉ cần sử dụng từ khoá
$this, trong đó đề cập đến chính đối tượng đó. Bằng cách này,
bạn có thể sử dụng
$this->filename để tham chiếu đặc
tính
filename của đối tượng thực thi đoạn mã này.
Bây giờ hãy xem xét việc thiết lập các giá trị cho các đặc tính này.
### Thiết lập các đặc tính
Thay vì chuyển thông tin tới một đối tượng, bạn muốn thực sự thiết lập các đặc tính của đối tượng đó:
<?php include ("../WFDocument.php"); $filetype = $_GET['filetype']; $filename = $_GET['file']; $wfdocument = new WFDocument();
$wfdocument->filename = $filename; $wfdocument->filetype = $filetype;$wfdocument->download (); ?>
Lưu ý ghi chú ở đây. Bạn đang sử dụng tên đối tượng là
$wfdocument, toán tử
-> và tên của đặc tính.
Một khi các đặc tính này đã được thiết lập, chúng có sẵn từ bên trong đối tượng, do
đó bạn không phải chuyển chúng đến phương thức
download().
Bây giờ, khi đã thực hiện tất cả điều đó, trong thực tế có một cách tốt hơn để xử lý loại điều này, vì vậy hãy xem xét một cách khác.
### Ẩn các đặc tính
Mặc dù dĩ nhiên
*có thể* trực tiếp thiết lập giá trị của một đặc tính, như bạn
đã làm trong phần trước, không có cách tốt nhất để xử lý những thứ này. Thay vào đó,
thói quen chung là ẩn giấu các đặc tính thực tế khỏi dùng chung và sử dụng
*getters* và *setters* để nhận và thiết lập các giá trị của chúng, giống
như sau:
<?php include_once("../scripts.txt"); class WFDocument {
private$filename; private$filetype; function setFilename($newFilename){ $this->filename = $newFilename; } function getFilename(){ return $this->filename; } function setFiletype($newFiletype){ $this->filetype = $newFiletype; } function getFiletype(){ return $this->filetype; }function download() { $filepath = UPLOADEDFILES.$this-> getFilename()if($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$this-> getFiletype()) print($file_contents); } } } ?>
Trước tiên, bạn định nghĩa các đặc tính là
private. Điều
đó có nghĩa là nếu bạn cố gắng thiết lập chúng trực tiếp, như bạn đã đang làm, bạn sẽ
nhận được một lỗi. Nhưng bạn vẫn phải thiết lập các giá trị này, nên thay vì bạn sử
dụng các phương thức
getFilename(),
setFilename(),
getFiletype() và
setFiletype(). Lưu ý rằng bạn sử dụng chúng ở đây theo phương
thức
download(), cũng giống như bạn đã sử dụng đặc tính
ban đầu.
Việc sử dụng getters và setters là tiện dụng vì nó cho phép bạn kiểm soát nhiều hơn qua những gì đang xảy ra với dữ liệu của bạn. Ví dụ, bạn có thể muốn thực hiện các việc kiểm tra xác nhận hợp lệ nào đó trước khi bạn cho phép thiết lập một giá trị cụ thể cho một đặc tính.
### Gọi các đặc tính ẩn
Bây giờ bạn đã ẩn các đặc tính, bạn cần phải quay lại và chỉnh sửa trang download_file.php để bạn không nhận được một lỗi:
<?php include ("../WFDocument.php"); $filetype = $_GET['filetype']; $filename = $_GET['file']; $wfdocument = new WFDocument(); $wfdocument->
setFilename($filename); $wfdocument-> setFiletype($filetype); $wfdocument->download(); ?>
Cách tiếp cận này là có ích, những có những cách dễ dàng hơn để thiết lập các đặc tính cho một đối tượng..
### Tạo một hàm tạo
Nếu một đối tượng có một hàm tạo (constructor), thì nó sẽ được gọi mỗi khi bạn tạo ra một biểu hiện mới của lớp cụ thể đó. Ví dụ, bạn có thể tạo một hàm tạo đơn giản:
... function getFiletype(){ return $this->filetype; }
function __construct(){ echo "Creating new WFDocument"; }function download() { $filepath = UPLOADEDFILES.$this->filename; ...
Nếu bạn cố gắng chạy như là kịch bản lệnh này, bạn sẽ thấy một lỗi vì đối tượng đó
xuất văn bản (
Creating new WFDocument) (Tạo WFDocument
mới) trước khi xuất các tiêu đề, như bạn thấy trong Hình 7.
##### Hình 7. Lỗi sau khi chạy kịch bản lệnh
![ Lỗi sau khi chạy kịch bản lệnh](phppart3fig7.jpg)
Vì vậy, ngay cả khi bạn chưa bao giờ gọi công khai phương thức
__construct(), ứng dụng này đã gọi nó ngay khi đối tượng được tạo. Bạn có
thể sử dụng điều đó cho lợi thế của bạn bằng cách thêm thông tin vào hàm tạo.
### Tạo một đối tượng có thông tin
Một trong những cách sử dụng phổ biến nhất với một hàm tạo là cung cấp một cách để
khởi tạo các giá trị khác nhau khi bạn tạo đối tượng. Ví dụ, bạn có thể thiết lập lớp
WFDocument để bạn thiết lập các đặc tính
filename và
filetype khi bạn tạo
đối tượng:
... function getFiletype(){ return $this->filetype; } function __construct(
$filename = "", $filetype = ""){ $this->setFilename($filename); $this->setFiletype($filetype);} function download() { $filepath = UPLOADEDFILES.$this->filename; ...
Khi bạn tạo đối tượng, PHP thực hiện bất kỳ hướng dẫn nào trong hàm tạo trước khi
tiếp tục. Trong trường hợp này, hàm tạo đó đang tìm kiếm
filename và
filetype. Nếu bạn không cung cấp
chúng, bạn vẫn sẽ không phải nhận một lỗi, bởi vì bạn đã xác định các giá trị mặc
định để sử dụng nếu không có giá trị nào được đưa ra khi hàm được gọi.
Nhưng bạn công khai gọi hàm
__construct()?
### Tạo đối tượng: Gọi các hàm tạo
Trên thực sự bạn không công khai gọi phương thức hàm tạo. Thay vào đó, bạn ngầm gọi nó mỗi khi bạn tạo một đối tượng. Điều đó có nghĩa là bạn sử dụng thời điểm cụ thể đó để chuyển thông tin cho các hàm tạo:
<?php include ("../WFDocument.php"); $filetype = $_GET['filetype']; $filename = $_GET['file']; $wfdocument = new WFDocument(
$filename, $filetype); $wfdocument->download(); ?>
Bất kỳ thông tin được chuyển cho lớp đó khi bạn tạo đối tượng mới được chuyển tới hàm tạo. Theo cách này, bạn có thể chỉ cần tạo đối tượng và sử dụng nó để tải về tập tin.
## Xử lý các trường hợp ngoại lệ
### Một ngoại lệ chung
Vì các ngoại lệ bắt đầu hoạt động khi một cái gì đó không hoàn toàn đúng với một ứng dụng, chúng thường bị nhầm lẫn với các lỗi. Tuy nhiên, các ngoại lệ linh hoạt hơn nhiều. Trong phần này, bạn sẽ thấy cách xác định các loại ngoại lệ khác nhau và sử dụng chúng để xác định điều sắp xảy ra với ứng dụng.
Hãy bắt đầu với một ngoại lệ chung đơn giản trong định nghĩa của lớp
WFDocument:
<?php include_once("../scripts.txt"); class WFDocument { ... function download() { $filepath = UPLOADEDFILES.$this->filename;
try { if(file_exists($filepath)){if ($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$this->filetype); print($file_contents); } } else { throw new Exception ("File '".$filepath."' does not exist."); } } catch (Exception $e) { echo "
".$e->getMessage()."
"; }} } ?>
Trước hết, các ngoại lệ không chỉ xảy ra, chúng được
*ném ra*. Và, tất nhiên,
nếu bạn ném một cái gì đó, bạn cần phải bắt giữ nó, vì vậy bạn tạo ra một câu lệnh
*try-catch* (thử-bắt giữ). Trong phần
try (thử),
bạn đưa ra mã của mình. Nếu một cái gì đó không thích hợp xảy ra, chẳng hạn như,
trong trường hợp này, một tập tin không tồn tại và bạn ném ra một ngoại lệ, PHP di
chuyển ngay tới khối
catch để bắt giữ ngoại lệ đó.
Một ngoại lệ có nhiều đặc tính, chẳng hạn như dòng và tập tin mà từ đó các ngoại lệ
được ném ra và một thông báo. Thông thường, ứng dụng thiết lập thông báo khi nó ném
ra ngoại lệ, như bạn thấy ở đây. Bản thân ngoại lệ,
$e,
sau đó cung cấp văn bản đó bằng cách sử dụng phương thức
getMessage(). Ví dụ, nếu bạn cố gắng để tải về một tập tin không tồn tại,
bạn sẽ thấy thông báo màu đỏ được hiển thị, như trong Hình 8.
##### Hình 8. Ngoại lệ cơ bản
![ Ngoại lệ cơ bản](phppart3fig8.jpg)
Tuy nhiên, sức mạnh thực sự của các ngoại lệ xuất phát từ việc tạo riêng của bạn.
### Tạo một ngoại lệ tùy chỉnh
Trong phần cuối, bạn kiểm tra các đối tượng, nhưng chúng tôi đã bỏ sót một khía cạnh rất quan trọng của chúng: đó là quyền thừa kế. Hãy xem xét điều đó bây giờ.
Một lợi thế để sử dụng các lớp là khả năng sử dụng một lớp làm cơ sở cho lớp khác. Ví
dụ, bạn có thể tạo một loại ngoại lệ mới,
NoFileExistsException, mở rộng lớp
Exception
(ngoại lệ) ban đầu:
class NoFileExistsException extends Exception { public function informativeMessage(){ $message = "The file, '".$this->getMessage()."', called on line ". $this->getLine()." of ".$this->getFile().", does not exist."; return $message; } }
(Để đơn giản, chúng tôi đã thêm mã này vào tập tin WFDocument.php, nhưng bạn có thể thêm nó vào bất cứ nơi nào nó có thể truy cập được khi bạn cần nó).
Ở đây, bạn đã tạo ra một lớp mới là,
NoFileExistsException, với một phương thức duy nhất:
informativeMessage(). Trong thực tế, lớp này
*cũng* là một
Exception, vì vậy tất cả những phương thức và đặc tính chung
nào cho một đối tượng
Exception cũng có sẵn.
Ví dụ, lưu ý rằng trong hàm
informativeMessage(), bạn gọi
phương thức
getLine() và
getFile(), mặc dù chúng không được định nghĩa ở đây. Chúng được định nghĩa
trong lớp cơ sở,
Exception, vì vậy bạn có thể sử dụng
chúng.
Bây giờ hãy xem ngoại lệ đang hoạt động.
### Bắt giữ một ngoại lệ tùy chỉnh
Cách dễ nhất để sử dụng loại ngoại lệ mới là đơn giản ném nó ra đúng như bạn muốn ném
một
Exception chung:
function download() { $filepath = UPLOADEDFILES.$this->filename; try { if(file_exists($filepath)){ if ($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$this->filetype); print($file_contents); } } else { throw new
NoFileExistsException ($filepath); } } catch ( NoFileExistsException$e) { echo "
".$e-> informativeMessage()."
"; } }
Lưu ý rằng ngay cả khi bạn chỉ chuyển
$filepath khi bạn
tạo ngoại lệ đó, bạn được thông báo đầy đủ trở lại, như trong Hình 9.
##### Hình 9. Sử dụng một ngoại lệ tùy chỉnh
![ Sử dụng một ngoại lệ tùy chỉnh](phppart3fig9.jpg)
### Làm việc với nhiều ngoại lệ
Một lý do để tạo các lớp của ngoại lệ tùy chỉnh là bạn có thể sử dụng khả năng của
PHP để phân biệt giữa chúng. Ví dụ, bạn có thể tạo nhiều khối
catch cho một
try duy nhất:
... function download() { $filepath = UPLOADEDFILES.$this->filename; try { if(file_exists($filepath)){ if ($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$this->filetype); print($file_contents); }
else { throw new Exception ("Cannot open file ".$filepath); }} else { throw new NoFileExistsException ($filepath); } } catch (NoFileExistsException $e) { echo "
".$e->informativeMessage()."
"; } catch (Exception $e){ echo "
".$e->getMessage()."
"; }} }
Trong trường hợp này, bạn cố gắng bắt giữ các vấn đề trước khi chúng xảy ra bằng cách
kiểm tra sự tồn tại của tập tin và ném ra một
NoFileExistsException. (ngoại lệ tập tin không tồn tại). Nếu bạn biết
trước rằng rào cản hay cái gì khác ngăn bạn mở tập tin đó, bạn ném ra một ngoại lệ
chung. PHP phát hiện các loại ngoại lệ mà bạn ném ra và thực thi các khối
catch thích hợp.
Tất cả điều này có vẻ hơi quá một chút để chỉ xuất ra các thông báo, nhưng đó không
phải tất cả những thứ mà bạn có thể làm. Bạn có thể tạo các phương thức tùy chỉnh cho
ngoại lệ của bạn, ví dụ, gửi các thông báo cho các sự kiện cụ thể. Bạn cũng có thể
tạo các khối
catch tùy chỉnh để thực hiện các hành động
khác nhau tùy theo tình hình.
Tất nhiên, chỉ vì bạn đã định nghĩa tất cả các ngoại lệ khác nhau không có nghĩa là bạn phải bắt giữ từng ngoại lệ riêng biệt, như bạn sẽ thấy tiếp theo.
### Lan truyền các ngoại lệ
Một tính năng tiện dụng của quyền thừa kế là khả năng xử lý một đối tượng như thể nó
đã là một thành viên của lớp cơ sở của nó. Ví dụ, bạn có thể ném ra một
NoFileExistsException và bắt giữ nó như là một
Exception chung:
... function download() { $filepath = UPLOADEDFILES.$this->filename; try { if(file_exists($filepath)){ if ($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$this->filetype); print($file_contents); } else { throw new Exception ("Cannot open file ".$filepath); } } else { throw new NoFileExistsException ($filepath); } } catch (Exception $e){ echo "
".$e->getMessage()."
"; } } }
Trong trường hợp này, khi bạn ném ra ngoại lệ đó, PHP hoạt động theo cách của nó đi
xuôi xuống danh sách các khối
catch, tìm kiếm một khối
catch đầu tiên để áp dụng. Ở đây bạn chỉ có một khối, nhưng khối đó sẽ bắt giữ
*bất
kỳ*
Exception nào, như trong Hình 10.
##### Hình 10. Lan truyền các ngoại lệ
![ Lan truyền các ngoại lệ](phppart3fig10.jpg)
## Đặt mọi thứ lại với nhau
### Bạn cần làm gì
Bây giờ bạn đã có quá trình tải tập tin tại chỗ, đó là lúc để đặt tất cả mọi thứ lại với nhau và hoàn thành ứng dụng. Trong phần này, bạn sẽ quan tâm đến một số nhiệm vụ linh tinh vẫn còn cần thực hiện:
- Tạo các trình định danh tập tin riêng.
- Phát hiện những người quản trị hệ thống.
- Tạo biểu mẫu để cho phép người quản trị hệ thống phê duyệt các tập tin.
- Kiểm tra phần tải xuống để đảm bảo chúng vẫn chưa được gọi từ máy chủ khác.
Bắt đầu bằng cách tạo ra một lớp
Counter (bộ đếm).
### Xác định các tài liệu cá nhân
Cho đến nay, bạn đã không lo lắng về việc xác định các tập tin cụ thể, trừ khi bạn đang tải chúng, nhưng bây giờ bạn cần phải chú ý nhiều hơn một chút nữa. Cuối cùng, bạn sẽ xử lý một biểu mẫu để cho phép một người quản trị phê duyệt các tập tin cụ thể, do đó sẽ thật có ích để có một cách dễ dàng để tham khảo chúng.
Điều bạn sắp làm ở đây là tạo một lớp
Counter để cho phép
bạn tạo một
*khóa* duy nhất cho mỗi tập tin. Sau đó bạn thêm khóa đó vào tập tin
XML, cho phép bạn trực tiếp yêu cầu phần tử
fileInfo thích
hợp. Bạn bắt đầu bằng cách tạo ra định nghĩa lớp
Counter.
Ví dụ, bạn có thể đặt nó trong tập tin scripts.txt:
class Counter{ function getNextId(){ $filename = "/usr/local/apache2/htdocs/counter.txt"; $handle = fopen($filename, "r+"); $contents = fread($handle, filesize($filename)); $nextid = $contents + 1; echo $nextid; rewind($handle); fwrite($handle, $nextid); fclose($handle); return $nextid; } }
Ở đây bạn có một hàm đơn,
getNextId(), để đọc một tập tin
hiện có, counter.txt và tăng các nội dung lên 1. (Vì vậy, trước khi bạn bắt đầu, hãy
tạo tập tin với mục nhập đơn là
0.) Sau đó hàm này quay
ngược lên đầu của tập tin và viết giá trị mới để giá trị đó sẽ có mặt khi bạn gọi hàm
lần tới.
Bạn sử dụng lớp này khi bạn thêm thông tin tập tin vào tập tin XML.
### Thêm trình định danh vào tập tin XML
Cuối cùng, bạn muốn có thể lấy ra một phần tử
fileInfo đơn
theo thuộc tính
ID của nó, vì thế hãy tiếp tục và thêm
thông tin này vào tập tin docinfo.xml được tạo ra trong "
[Học
PHP, Phần 2](http://www.ibm.com/developerworks/vn/edu/os-phptut2/index/index.html)."
function save_document_info($fileInfo){ $xmlfile = UPLOADEDFILES."docinfo.xml"; ... $filename = $fileInfo['name']; $filetype = $fileInfo['type']; $filesize = $fileInfo['size']; $fileInfo = $doc->createElement("fileInfo");
$counter = new Counter(); $fileInfo->setAttribute("id", "_".$counter->getNextId());$fileInfo->setAttribute("status", "pending"); $fileInfo->setAttribute("submittedBy", getUsername()); ... $doc->save($xmlfile); }
Mỗi khi thông tin của một tài liệu mới được lưu, bạn tạo một đối tượng
Counter và sử dụng phương thức
getNextId() của nó để cung cấp một giá trị duy nhất cho thuộc tính
id. Vì sau đó bạn sẽ xác định thuộc tính này theo kiểu
ID, bạn sẽ định trước giá trị với một dấu gạch dưới (
_) vì các giá trị này không thể bắt đầu bằng một số.
Các kết quả trông giống như sau (chúng tôi thêm vào khoảng trống để làm cho nó dễ đọc hơn một chút):
<fileInfo
id="_13"status="pending" submittedBy="roadnick"> <approvedBy/> <fileName>timeone.jpg</fileName> <location>/var/www/hidden/</location> <fileType>image/jpeg</fileType> <size>2020</size> </fileInfo>
Lưu ý rằng quá trình này không ảnh hưởng đến bất kỳ dữ liệu hiện có nào của bạn, vì
vậy bằng cách thủ công bạn cần thêm vào các thuộc tính
id
cho tất cả các phần tử
fileInfo của bạn hoặc xóa tập tin
docinfo.xml và bắt đầu lại, tải lên các tập tin để làm việc với chúng.
Bây giờ bạn đã sẵn sàng phê duyệt các tập tin, nhưng trước tiên bạn cần phải thiết lập những người quản trị hệ thống để thực hiện việc đó.
### Phát hiện những người quản trị hệ thống
Khi lúc đầu bạn đã tạo bảng người sử dụng trong cơ sở dữ liệu, bạn đã không tính đến thực tế là bạn đã cần phân biệt giữa những người sử dụng thường xuyên với những người quản trị hệ thống, vì vậy bạn phải quan tâm đến điều đó bây giờ. Đăng nhập vào MySQL và thực hiện các lệnh sau:
alter table users add status varchar(10) default 'USER'; update users set status = 'USER'; update users set status = 'ADMIN' where id=3;
Lệnh đầu tiên thêm cột mới,
status (trạng thái), vào bảng
users (những người dùng). Bạn không xác định loại người dùng trên trang đăng ký, vì
vậy bạn chỉ cần xác định một giá trị mặc định của
USER cho
bất kỳ người dùng mới nào được bổ sung vào hệ thống. Lệnh thứ hai thiết lập trạng
thái này cho những người sử dụng hiện có. Cuối cùng, bạn chọn một người sử dụng làm
người quản trị. (Hãy chắc chắn sử dụng giá trị
id thích
hợp cho dữ liệu của bạn).
Bây giờ bạn có dữ liệu, bạn có thể tạo một hàm để trả về trạng thái của người sử dụng hiện tại:
function getUserStatus(){ $username = $_SESSION["username"]; db_connect(); $sql = "select * from users where username='".$username."'"; $result = mysql_query($sql); $row = mysql_fetch_array($result); $status = ""; if ($row) { $status = $row["status"]; } else { $status = "NONE"; } mysql_close(); return $status; }
Chúng ta hãy xem lại cách quá trình này hoạt động như thế nào. Trước tiên, bạn tạo
một kết nối đến cơ sở dữ liệu phù hợp bằng cách sử dụng kịch bản lệnh mà bạn đã tạo:
db_connect(). Sau đó bạn có thể tạo ra một câu lệnh SQL
bằng cách sử dụng tên người dùng, được lưu trữ trong biến
$_SESSION. Tiếp theo, bạn thực hiện câu lệnh đó và cố gắng để có được dòng
dữ liệu (và có lẽ chỉ một dòng) đầu tiên.
Nếu có một hàng tồn tại, bạn thiết lập trạng thái bằng giá trị của cột
status. Nếu không, bạn thiết lập trạng thái bằng
NONE (không). Cuối cùng, đóng kết nối và trả về giá trị.
Đặt hàm này trong tập tin scripts.txt để bạn có thể truy cập nó khi bạn hiển thị danh sách tập tin.
### Phê duyệt tập tin đó: Biểu mẫu
Bây giờ bạn đã sẵn sàng để thêm các khả năng phê duyệt cho biểu mẫu đó. Điều bạn muốn
là hiển thị một hộp kiểm tra cho các tập tin đang chờ giải quyết nếu người dùng xem
danh sách các tập tin là người quản trị hệ thống. Lớp
Content_Handler xử lý hiển thị này:
class Content_Handler{ private $available = false; private $submittedBy = ""; private $status = ""; private $currentElement = "";
private $fileId = "";private $fileName = ""; private $fileSize = ""; private $fileType = ""; private $userStatus = "";function start_element($parser, $name, $attrs){ if ($name == "workflow"){ $this->userStatus = getUserStatus($_SESSION["username"]); if ($this->userStatus == "ADMIN"){ echo "<form action='approve_action.php' method='POST'>"; }echo "
Available files
"; echo "

". "File Name	Submitted By	". "Size	Status	 "; if ($this->userStatus == "ADMIN"){ echo "Approve	"; } echo "
"; } if ($name == "fileInfo"){ if ($attrs['status'] == "approved" || $attrs['submittedBy'] == $this->username){ $this->available = true; } if ($this->available){ $this->submittedBy = $attrs['submittedBy']; $this->status = $attrs['status']; $this->fileId = $attrs['id']; } } $this->currentElement = $name; } function end_element($parser, $name){ if ($name == "workflow"){ echo "
"; if ($this->userStatus == "ADMIN"){ echo "<input type='submit' value='Approve Checked Files' />"; echo "</form>"; }} if ($name == "fileInfo"){ echo "
"; echo "fileName."&filetype=". $this->fileType."'>". $this->fileName."	". "".$this->submittedBy."	". "".$this->fileSize."	". "".$this->status."	 "; if ($this->userStatus == "ADMIN"){ if ($this->status == "pending") { echo "<input type='checkbox' name='toapprove[]' value='". $this->fileId." ' checked='checked' />"; } } echo "
"; $this->fileId = "";$this->fileName = ""; $this->submittedBy = ""; $this->fileSize = ""; $this->status = ""; $this->fileType = ""; $this->available = false; } $this->currentElement = ""; } function chars($parser, $chars){ ... } }
Bắt đầu từ trên cùng, bạn có hai đặc tính mới để định nghĩa:
$fileId và
$userStatus. Đặc tính sau, bạn thiết
lập chỉ một lần, khi bạn xử lý sự khởi đầu của phần tử
workflow và, vì thế, là sự khởi đầu của tài liệu. Tại thời điểm này, nếu
người dùng
*là* một người quản trị, bạn muốn thêm vào một phần tử
form biểu mẫu vào trang đó và một cột
Approve (phê duyệt) vào bảng đó.
Bạn đóng biểu mẫu ở cuối của tài liệu, khi trình xử lý nội dung nhận được thông báo
về sự kết thúc của phần tử
workflow.
Đối với các hộp kiểm tra thực tế, bạn xuất các hộp này ra khi bạn hiển thị hàng thông
tin ở cuối của mỗi phần tử
fileInfo. Vì bạn có tiềm năng
cho nhiều mục nhập, bạn đặt tên trường là
toapprove[].
Kết quả là một biểu mẫu với các hộp thích hợp, như bạn có thể thấy trong Hình 11.
##### Hình 11. Biểu mẫu phê duyệt
![ Biểu mẫu phê duyệt](phppart3fig11.jpg)
### Thiết lập các ID
Bây giờ bạn đã có biểu mẫu, nhưng để truy cập vào các phần tử
fileInfo bằng các thuộc tính
id của chúng, bạn
cần phải thêm nhiều hơn một bước. Không giống như trong một tài liệu HTML, chỉ cần
đặt tên một thuộc tính "id" là chưa đủ để làm cho nó hành động giống như một trình
định danh. Trong một tập tin XML, bạn phải cung cấp một số loại lược đồ (chú ý chữ
"s" nhỏ) để định nghĩa thuộc tính. Trong trường hợp này, bạn sẽ thêm một DTD (Định
nghĩa kiểu tài liệu). Trước tiên, bạn thêm một tham chiếu đến nó trong tài liệu thực
tế:
function save_document_info($fileInfo){ $xmlfile = UPLOADEDFILES."docinfo.xml"; if(is_file($xmlfile)){ $doc = DOMDocument::load($xmlfile); $workflowElements = $doc->getElementsByTagName("workflow"); $root = $workflowElements->item(0); $statistics = $root->getElementsByTagName("statistics")->item(0); $total = $statistics->getAttribute("total"); $statistics->setAttribute("total", $total + 1); } else{
$domImp = new DOMImplementation; $dtd = $domImp->createDocumentType('workflow', '', 'workflow.dtd'); $doc = $domImp->createDocument("", "", $dtd);$root = $doc->createElement('workflow'); $doc->appendChild($root); $statistics = $doc->createElement("statistics"); $statistics->setAttribute("total", "1"); $statistics->setAttribute("approved", "0"); $root->appendChild($statistics); } ... }
Thay vì tạo tài liệu trực tiếp bằng cách tạo lớp
DOMDocument, bạn tạo một
DOMImplementation, từ
đó bạn tạo một đối tượng DTD. Sau đó bạn gán DTD đó cho tài liệu mới mà bạn đang
tạo.
Nếu bạn gỡ bỏ tập tin docinfo.xml và tải lên một tài liệu mới, bạn sẽ thấy thông tin mới:
<?xml version="1.0"?>
<!DOCTYPE workflow SYSTEM "workflow.dtd"><workflow> <statistics total="3" approved="0"/> ...
Bây giờ bạn cần phải tạo tập tin workflow.dtd.
### DTD
Việc giải thích tất cả các sắc thái của việc xác nhận hợp lệ XML là vượt quá xa phạm vi của hướng dẫn này, nhưng bạn cần phải có một DTD để mô tả cấu trúc của tập tin docinfo.xml. Để làm điều đó, hãy tạo một tập tin và lưu nó như là tập tin workflow.dtd trong cùng một thư mục với tập tin docinfo.xml. Thêm vào như sau:
<!ELEMENT workflow (statistics, fileInfo*) > <!ELEMENT statistics EMPTY> <!ATTLIST statistics total CDATA #IMPLIED approved CDATA #IMPLIED > <!ELEMENT fileInfo (approvedBy, fileName, location, fileType, size)>
<!ATTLIST fileInfo id ID #IMPLIED><!ATTLIST fileInfo status CDATA #IMPLIED> <!ATTLIST fileInfo submittedBy CDATA #IMPLIED> <!ELEMENT approvedBy (#PCDATA)> <!ELEMENT fileName (#PCDATA)> <!ELEMENT location (#PCDATA)> <!ELEMENT fileType (#PCDATA)> <!ELEMENT size (#PCDATA)>
Để đơn giản, bạn định nghĩa mỗi phần tử và mô hình "nội dung"của nó. Ví dụ, phần tử
workflow phải có một phần tử con
statistics và không có hoặc có nhiều phần tử con
fileInfo hơn nữa.
Bạn cũng định nghĩa các thuộc tính và các kiểu của chúng. Ví dụ, phần tử
statistics có hai thuộc tính tùy chọn,
total (tổng số) và
approved (được phê duyệt) và
chúng đều là dữ liệu ký tự.
Ở đây khóa là định nghĩa của giá trị
id của phần tử
fileInfo, mà bạn đã định nghĩa theo loại
ID.
Bây giờ bạn có thể sử dụng thông tin này.
### Phê duyệt tập tin: Cập nhật XML
Trang biểu mẫu thực tế chấp nhận các hộp kiểm tra phê duyệt, approve_action.php, rất đơn giản:
<?php include "../scripts.txt"; $allApprovals = $_POST["toapprove"]; foreach ($allApprovals as $thisFileId) { approveFile($thisFileId); } echo "Files approved."; ?>
Đối với mỗi hộp kiểm tra
toapprove, bạn chỉ cần gọi hàm
approveFile(), trong scripts.txt:
function approveFile($fileId){ $xmlfile = UPLOADEDFILES."docinfo.xml"; $doc = new DOMDocument(); $doc->validateOnParse = true; $doc->load($xmlfile); $statisticsElements = $doc->getElementsByTagName("statistics"); $statistics = $statisticsElements->item(0); $approved = $statistics->getAttribute("approved"); $statistics->setAttribute("approved", $approved+1); $thisFile = $doc->getElementById($fileId); $thisFile->setAttribute("status", "approved"); $approvedByElements = $thisFile->getElementsByTagName("approvedBy"); $approvedByElement = $approvedByElements->item(0); $approvedByElement->appendChild($doc->createTextNode($_SESSION["username"])); $doc->save($xmlfile); }
Trước khi bạn còn tải các tài liệu, bạn xác định rằng bạn muốn trình phân tích cú
pháp xác nhận hợp lệ nó hoặc kiểm tra nó so với DTD. Điều này thiết lập tính chất của
thuộc tính
id. Một khi bạn đã tải tập tin, bạn sẽ có được
một tham chiếu đến phần tử
statistics để bạn có thể tăng
số lượng các tập tin được phê duyệt.
Bây giờ bạn đã sẵn sàng để thực sự phê duyệt tập tin. Vì bạn thiết lập thuộc tính
id như là một giá trị kiểu -
ID, nên bạn có thể sử dụng
getElementById() để
yêu cầu phần tử
fileInfo thích hợp. Khi bạn có phần tử đó,
bạn có thể thiết lập
status (trạng thái) của nó tới
approved.
Bạn cũng cần có được một tham chiếu tới phần tử con
approvedBy của phần tử này. Khi bạn đã có tham chiếu đó, bạn có thể thêm
một phần tử con của nút
Text mới với tên người dùng của
người quản trị.
Cuối cùng, lưu tập tin.
Lưu ý rằng trong khi bạn đã thực hiện tập tin theo cách này để đơn giản, thì trong một ứng dụng sản xuất, hiệu quả hơn là mở và tải tập tin chỉ một lần, tạo ra tất cả các thay đổi, sau đó lưu tập tin.
### Kiểm tra an ninh lúc tải về
Là bước cuối cùng, bạn thêm một việc kiểm tra an ninh cho quá trình tải về. Vì bạn kiểm soát toàn bộ quá trình này thông qua ứng dụng, nên bạn có thể sử dụng bất cứ việc kiểm tra nào bạn muốn. Ví dụ này, bạn sẽ kiểm tra để đảm bảo rằng người dùng đã nhấn vào liên kết với một tập tin trên một trang ở trên máy chủ nội bộ của bạn, ngăn người khác khỏi liên kết đến nó từ một trang web bên ngoài hoặc thậm chí ngăn nó khỏi đánh dấu liên kết hoặc gửi cho một ai đó một liên kết thô.
Bạn bắt đầu bằng cách tạo một ngoại lệ mới, đúng lúc này, trong tập tin WFDocument.php:
<?php include_once("../scripts.txt"); class NoFileExistsException extends Exception { public function informativeMessage(){ $message = "The file, '".$this->getMessage()."', called on line ". $this->getLine()." of ".$this->getFile().", does not exist."; return $message; } }
class ImproperRequestException extends Exception { public function logDownloadAttempt(){ //Additional code here echo "Notifying administrator ..."; } }class WFDocument { private $filename; private $filetype; function setFilename($newFilename){ $this->filename = $newFilename; } function getFilename(){ return $this->filename; } function setFiletype($newFiletype){ $this->filetype = $newFiletype; } function getFiletype(){ return $this->filetype; } function __construct($filename = "", $filetype = ""){ $this->setFilename($filename); $this->setFiletype($filetype); } function download() { $filepath = UPLOADEDFILES.$this->filename; try { $referer = $_SERVER['HTTP_REFERER']; $noprotocol = substr($referer, 7, strlen($referer)); $host = substr($noprotocol, 0, strpos($noprotocol, "/")); if ( $host != 'boxersrevenge' && $host != 'localhost'){ throw new ImproperRequestException("Remote access not allowed. Files must be accessed from the intranet."); }if(file_exists($filepath)){ if ($stream = fopen($filepath, "rb")){ $file_contents = stream_get_contents($stream); header("Content-type: ".$this->filetype); print($file_contents); } else { throw new Exception ("Cannot open file ".$filepath); } } else { throw new NoFileExistsException ($filepath); } } catch (ImproperRequestException $e){ echo "
".$e->getMessage()."
"; $e->logDownloadAttempt(); }catch (Exception $e){ echo "
".$e->getMessage()."
"; } } } ?>
Trước hết, trong
ImproperRequestException, bạn tạo một
phương thức mới là,
logDownloadAttempt(), để có thể gửi
một e-mail hoặc thực hiện một số hành động khác. Bạn sử dụng phương thức đó trong
khối
catch của kiểu ngoại lệ này.
Trong hàm
download() thực tế, điều đầu tiên bạn làm là
nhận
HTTP_REFERER. Phần tiêu đề của tùy chọn này được gửi
với một yêu cầu web xác định trang để thực hiện yêu cầu từ đó. Ví dụ, nếu bạn liên
kết với
[developerWorks](http://www.ibm.com/developerworks) từ blog của
bạn và bạn nhấn vào liên kết đó, các bản ghi của IBM sẽ hiển thị các URL của blog của
bạn như là
HTTP_REFERER cho truy cập đó.
Trong trường hợp của bạn, bạn muốn chắc chắn yêu cầu sẽ đến từ ứng dụng của bạn, vì vậy đầu tiên bạn gỡ bỏ chuỗi "http://" ở đầu, sau đó lưu tất cả văn bản cho đến dấu gạch chéo ngược đầu tiên (/). Đây là tên máy chủ trong yêu cầu.
Đối với một yêu cầu bên ngoài, tên máy chủ này có thể là một cái gì đó dọc theo các
dòng boxersrevenge.nicholaschase.com, nhưng bạn đang tìm kiếm chỉ các yêu cầu nội bộ,
vì vậy bạn chấp nhận
boxersrevenge hay
localhost. Nếu yêu cầu đến từ bất cứ nơi nào khác, bạn ném ra
ImproperRequestException, để khối thích hợp bắt giữ.
Lưu ý rằng phương thức này là không dễ sử dụng đối với an ninh. Một số trình duyệt không gửi đúng thông tin muốn chọn vì hoặc là chúng không hỗ trợ nó hoặc người sử dụng đã thay đổi những gì đang được gửi. Nhưng ví dụ này sẽ cho bạn một ý tưởng về các loại công việc mà bạn có thể làm để trợ giúp kiểm soát nội dung của bạn.
## Tóm tắt
Hướng dẫn này hoàn thành loạt bài ba phần về "Học PHP" trong khi bạn xây dựng một ứng dụng tiến trình công việc đơn giản. Các phần trước đó tập trung vào các vấn đề cơ bản, như cú pháp, xử lý biểu mẫu, truy cập cơ sở dữ liệu, tải lên tập tin và XML. Trong phần này, bạn đưa tất cả điều đó tiến lên một bước nữa và đặt nó lại với nhau bằng cách tạo ra một biểu mẫu để qua đó một người quản trị hệ thống có thể phê duyệt các tập tin khác nhau. Chúng ta đã thảo luận các chủ đề sau:
- Sử dụng xác thực HTTP.
- Tạo luồng các tập tin.
- Tạo các lớp và các đối tượng.
- Các đặc tính và các phương thức đối tượng.
- Sử dụng các hàm tạo đối tượng.
- Sử dụng các ngoại lệ.
- Tạo các ngoại lệ tùy chỉnh.
- Sử dụng các thuộc tính ID của XML.
- Thực hiện các việc kiểm tra an ninh bổ sung cho tải về
## Tài nguyên
### Học tập
- Đọc
[Phần 1](http://www.ibm.com/developerworks/vn/edu/os-phptut1/index.html)và [Phần 2](http://www.ibm.com/developerworks/vn/edu/os-phptut2/index.html)của loạt bài này: "Học PHP".
- Đọc
[Hướng dẫn sử dụng PHP](http://www.php.net/manual/en). [Hướng dẫn sử dụng PHP: Các lớp và các đối tượng (PHP V4)](http://www.php.net/manual/en/language.oop.php)và [Hướng dẫn sử dụng PHP: Các lớp và các đối tượng (PHP V5)](http://www.php.net/manual/en/language.oop5.php)mỗi hướng dẫn có nhiều thông tin.
- Đọc về các ngoại lệ trong
[Hướng dẫn sử dụng PHP: Các ngoại lệ](http://www.php.net/manual/en/language.exceptions.php).
- Đọc về an ninh trong
[Hướng dẫn sử dụng PHP: An ninh](http://www.php.net/manual/en/security.php).
- Đọc về xác thực HTTP trong
[Hướng dẫn sử dụng PHP: Xác thực HTTP với PHP](http://www.php.net/manual/en/features.http-auth.php).
- Đọc về các hàm DOM trong
[Hướng dẫn sử dụng PHP: Các hàm DOM](http://www.php.net/manual/en/ref.dom.php).
- Tìm hiểu về các hàm luồng trong
[Hướng dẫn sử dụng PHP: Các hàm luồng](http://www.php.net/manual/en/ref.stream.php).
- Tìm hiểu về các hàm chuỗi trong
[Hướng dẫn sử dụng PHP: Các hàm chuỗi](http://www.php.net/manual/en/ref.strings.php).
- Đọc
[Hướng dẫn sử dụng PHP: Streams API với các tác giả của phần mở rộng PHP](http://www.php.net/manual/en/streams.php).
- Đọc về
[Xác thực, Cấp phép và Kiểm soát truy cập của máy chủ HTTP Apache phiên bản 1.3](http://httpd.apache.org/docs/howto/auth.html)và [Xác thực, Cấp phép và Kiểm soát truy cập của máy chủ HTTP Apache phiên bản 2.0](http://httpd.apache.org/docs-2.0/howto/auth.html).
- Đọc
[Hướng dẫn máy chủ HTTP Apache phiên bản 2.0: các tập tin .htaccess.](http://httpd.apache.org/docs-2.0/howto/htaccess.html).
- Truy cập
[các tài nguyên của dự án PHP](http://www.ibm.com/developerworks/opensource/top-projects/php.html?S_TACT=105AGY75)của developerWorks IBM để tìm hiểu thêm về PHP.
- Theo sát với
[các sự kiện kỹ thuật và webcast của developerWorks](http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGY75).
- Xem các hội nghị sắp tới, các triển lãm thương mại,
webcast và
[các sự kiện](http://www.ibm.com/developerworks/views/opensource/events.jsp?S_TACT=105AGY75)khác trên khắp thế giới đang được các nhà phát triển mã nguồn mở của IBM quan tâm.
- Truy cập tới
[vùng mã nguồn mở của developerWorks](http://www.ibm.com/developerworks/opensource?S_TACT=105AGY75)với các thông tin hướng dẫn phong phú, các công cụ và cập nhật dự án để giúp bạn phát triển với các công nghệ mã nguồn mở và sử dụng chúng với các sản phẩm của IBM.
- Nghe các cuộc phỏng vấn và thảo luận thú vị với các
nhà phát triển phần mềm, đừng quên xem
[podcast của developerWorks](http://www.ibm.com/developerworks/podcast/?S_TACT=105AGY75).
### Lấy sản phẩm và công nghệ
- Đổi mới dự án phát triển mã
nguồn mở tiếp theo của bạn với
[phần mềm dùng thử của IBM](http://www.ibm.com/developerworks/downloads/?S_TACT=105AGY75), có sẵn để tải hoặc trên đĩa DVD.
### Thảo luận
- Hãy dành hết tâm trí cho cộng đồng developerWorks
bằng cách tham gia vào
[các blog của developerWork](http://www.ibm.com/developerworks/blogs/?S_TACT=105AGY75).
## Bình luận
[Vùng dữ liệu trên developerWorks](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp)
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
[Vùng mã nguồn mở trên developerWorks](http://www.ibm.com/developerworks/vn/views/opensource/libraryview.jsp)
Xem các bài viết về HTML, CSS, JavaScript,...
[Điện toán đám mây](http://www.ibm.com/developerworks/vn/views/cloud/libraryview.jsp)
Tìm hiểu về điện toán đám mây

Content-Language: en-US

Kp-eeAlive: timeout=10, max=92


markdown:
![](/etc/designs/ver/5.1.21/intel/us/en/images/printlogo.png)
# Các kiểu Đánh giá
![Các kiểu Đánh giá Các kiểu Đánh giá](/content/dam/www/program/education/apac/in/en/images/types-of-assessment-3x2.jpg.rendition.cq5dam.webintel.200.132.jpg)
## Đánh giá bằng nhiều cách khác nhau
Đánh giá là một hoạt động phổ biến trong lớp học hiện nay. Đánh giá thường diễn ra bằng những hình thức có thể dự đoán được theo phương pháp truyền thống. Tuy nhiên, có nhiều cách đánh giá khác nhau để lựa chọn nhằm đáp ứng được nhu cầu dạy học của giáo viên và nhu cầu học tập của học sinh.
**Đánh giá thành phần**
Mặc dù những bài kiểm tra và các kỳ thi sẽ vẫn tồn tại trong nhà trường, nhưng việc học của học sinh có thể được cải thiện tốt hơn khi thông tin của nhiều loại hình đánh giá khác nhau được sử dụng để thông báo việc dạy học, cung cấp thông tin phản hồi và đánh giá các sản phẩm và kỹ năng. Hình thức đánh giá diễn ra trước và trong một đơn vị bài học được gọi là đánh giá thành phần.
Nhiều kỹ thuật trong đánh giá thành phần cung cấp cho giáo viên và học sinh loại thông tin cần thiết để thúc đẩy việc học:
- Kỹ thuật để theo dõi nhu cầu của học sinh, như là xem xét công việc của học sinh, phân tích bảng biểu đồ họa, và động não
- Kỹ thuật khuyến khích khả năng tự định hướng như tự đánh giá, phản hồi từ bạn học và làm việc cộng tác trong nhóm
- Kỹ thuật theo dõi sự tiến bộ, như là những nhận xét không chính thức, ghi chép, những nhật ký học tập
- Những kỹ thuật kiểm tra khả năng lĩnh hội như các tập san, những cuộc phỏng vấn và chất vấn thân mật.
**Đánh giá tổng thể
**Trong khi đánh giá thành phần có thể cho học sinh và giáo viên biết được họ đang học và dạy ở mức độ nào trong quá trình thực hiện một dự án học tập thì trong một trường hợp khác, hầu hết các giáo viên phải có báo cáo về kết quả học tập của học sinh vào cuối một bài học hoặc một dự án cụ thể. Học sinh cũng muốn biết và cần biết những công việc các em đã làm có kết quả ra sao. Kiểu đánh giá thực hiện sau khi mọi việc đã hoàn tất như vậy gọi là đánh giá tổng thể.
Đánh giá tổng thể, giống như bài kiểm tra mỗi đơn vị bài học, có thể cung cấp thông tin hữu ích nếu giáo viên và học sinh dành thời gian phân tích các bài kiểm tra đó. Giáo viên có thể tìm ra những điểm yếu để chú tâm nhiều hơn trong những bài học và các lớp học tới. Học sinh có thể phát hiện ra những chỗ có vấn đề và thiết lập mục tiêu học tập trong tương lai.
#### Tình huống đánh giá
So sánh kết quả của học sinh ở hai lớp khác nhau, một lớp có cách đánh giá truyền thống, một lớp khác có cách đánh giá thường xuyên và liên tục.
#### Những chủ đề đặc biệt về Đánh giá
- Đọc Thêm
-
- ˄
- ˅

WARC-Type: response

Content-Type: application/http; msgtype=response

Content-Type: text/html

Accept-Ranges: bytes

X-Powered-By: ASP.NET; PA05

x-frame-options: sameorigin

Vary: Accept-Encoding

Content-Encoding: gzip

Connection: close


markdown:
[Cài Đặt Java Tại Đây](http://java.com/en/download/index.jsp)Để Xem Được Tất Cả Các Server Nhé Cả Nhà [2013,](http://www.kenh99.com/) **Phim Hay** [,](http://www.kenh99.com/2012/05/xem-hoat-hinh-doremon-tap-1-full.html) **Xem Hoat Hinh Doremon** [,](http://www.kenh99.com/2012/06/phim-hoat-hinh-hay-nhat-2012-2013.html) **Phim Hoat Hinh Hay**
Phim Hoạt Hình Doremon Tập 20
[Cánh Tay Đáp Trả](http://www.kenh99.com/2012/06/phim-hoat-hinh-doremon-tap-20-canh-tay.html)
Phim hoat hinh doremon ,Xem hoạt hình đô rê mon,Xem hoạt hình do re mon tập 20 full ,hoạt hình doremon tập 20 ,xem phim hoạt hình doremon,phim hoạt hình doraemon,download phim hoat hinh doremon tieng viet tập 20 ,phim hoat hinh doremon tieng viet,hoat hinh do re mon tieng viet tap 20
Phim Đề Cử :
[Xem Hoạt Hình Đô rê mon](http://www.kenh99.com/2012/03/hoat-hinh-doremon-nobita-tay-du-ky-full.html)Nobita Tây Du Ký Cực Hay [Hoạt Hình Dorenon](http://www.kenh99.com/2012/05/xem-hoat-hinh-doremon-tap-1-full.html)Tập 1 Full
Các câu chuyện trong Đôrêmon thường có một công thức chung, đó là xoay quanh những rắc rối hay xảy ra với cậu bé Nôbita lớp bốn, nhân vật chính của bộ truyện. Đôrêmon có một chiếc túi thần kỳ trước bụng với đủ loại bảo bối của tương lai. Cố
**Cùng chủ đề cần tìm :**Phim Hoat Hinh Doremon, Hoat hinh tieng viet do re mon tập 20, hoat hinh do re mon tieng viet,bo phim hoat hinh do re mon,coi phim hoat hinh do re mon tập 20 ,phim hoạt hình do re mon,xem hoạt hình online,xem hoat hinh do re mon tap cuoi,xem phim hoat hinh do re mon tap 20 [Xem Phim Nhanh Nhất](http://www.kenh99.com/)trên Kênh 99 Xem Là Mê

WARC-Truncated: length

Content-Type: text/html; charset=UTF-8

Cache-Control: private, max-age=0

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Server: GSE


markdown:
Giúp bạn mang những chiếc bánh ra khỏi khuôn một cách dễ dàng, đặc biệt thích hợp cho cheesecake và mousse
Những chiếc khuôn đúc bằng nhôm đa dạng giúp bạn tạo những chiếc bánh thật đặc biệt một cách đơn giản
Trang bị cho bạn những chiếc khuôn chống dính xinh xắn và tiện dụng để mỗi chiếc bánh bạn làm đều trông như chuyên nghiệp

Server: Apache

X-Powered-By: PleskLin


markdown:
Thái Bảo
03-04-2010, 09:11 AM
Sữa chua là một món ăn rất bổ dưỡng thích hợp cho mọi người hàng ngày, vì vậy Mẹ nào biết cách làm sữa chua hoàn toàn bằng sữa tươi , chỉ cho với nhé! Thanks nhé!
View Full Version :
[tư vấn cách làm sữa chua bằng sữa tươi](http://www.lamchame.com/forum/showthread.php/110831-tư-vấn-cách-làm-sữa-chua-bằng-sữa-tươi?s=2ca594d3da7e3806e343b94d0f460c30)

Server: nginx

Content-Type: text/html; charset=utf-8

Pragma: private

Set-Cookie: lcm_lastactivity=0; expires=Wed, 21-Oct-2015 10:21:43 GMT; path=/

Vary: Accept-Encoding,User-Agent


markdown:
# Geocaching
![ L.L.Bean Outdoor Discovery Schools.](/dept_resources/ODS/images/140721_ODS_ActivityLanderGeo.jpg)
![ Uncover hidden treasures](/dept_resources/ODS/images/140721_ODS_ActivityLanderGeo_TEXT.png)
Join us for a real world treasure hunt – geocaching is a great way to get outside and search the landscape for hidden treasures. Look below to sign up for an adventure that's just right for you.
|Date/Time||Event||Location||Price|
|No scheduled events matching your search.|

Content-Type: text/html; charset=iso-8859-1

Set-Cookie: LLBSN=Test01; expires=Sat, 20-Dec-2014 11:15:04 GMT; path=/; domain=.www.llbean.com

Pragma: no-cache

P3P: CP="CAO DSP COR CURa ADMa DEVa TAIa PSAa PSDa CONo OUR DELa TRo IND PHY ONL UNI PUR FIN COM NAV DEM STA", policyref="/w3c/p3p.xml"

X-UA-Compatibility: IE=edge

X-Frame-Options: DENY

X-dynaTrace-JS-Agent: true


markdown:
Tweet
[Kara + Effect] Ngây Ngô - Hoàng Yến Chibi Mp3 Download
Ngây ngô - Hoàng Yến Chibi + Kara mp3
Last listened by TAMMYALVARADO and HUTCHINSON35 | Duration: 04:57 | Size: 3.0mb
Download
Play
Ngây Ngô - Hoàng Yến Chibi mp3
Last listened by pruitt10 and _simon40 | Duration: 04:56 | Size: 1.1mb
Download
Play
[Kara + Effect] Ngây Ngô - Hoàng Yến Chibi mp3
Last listened by CHIN29 and JACKIE20 | Duration: 04:58 | Size: 1.5mb
Download
Play
Karaoke] Ngây ngô - Hoàng Yến - http://newtitanvn.com mp3
Last listened by MILES and norton_ | Duration: 05:09 | Size: 4.4mb
Download
Play
Karaoke] Ngây ngô - Hoàng Yến Chibi mp3
Last listened by __HORNE__ and __eloise_mcgowan | Duration: 04:38 | Size: 4.8mb
Download
Play
MV - HD / 720p] Ngây Ngô-Hoàng Yến Chibi mp3
Last listened by MERNA and NICOLETTE | Duration: 04:55 | Size: 4.5mb
Download
Play
[MVHD Kara+Lyric] Ngây Ngô - Hoàng Yến Chibi 999.999.999 view mp3
Last listened by macie_ and MONROE_ | Duration: 04:56 | Size: 4.8mb
Download
Play
Ngây Ngô - Hoàng Yến MV Part 1 mp3
Last listened by kirby and joana27 | Duration: 04:57 | Size: 1.4mb
Download
Play
[Sub+kara] Ngây ngô - Chibi Hoàng Yến mp3
Last listened by __garner43 and __ajalloyd | Duration: 04:54 | Size: 2.6mb
Download
Play
HD] mp3
Last listened by FLYNN__ and _MCMAHON | Duration: 04:57 | Size: 2.7mb
Download
Play
NGÂY NGÔ-HOÀNG YẾN CHIBI
mp3

Cache-Control: private

Vary: Accept


markdown:
|Röd storm - |FESTUNG EUROPA ................................ ![]()
|Lakej -| LAKEJ - EU .................................................. ![]()
**VI LÅTER OSS INTE LURAS**............... [.......](mp3/vi_later_oss_inte_luras.mp3) ![](bilder/mp3.jpg)
![](bilder/mp3.jpg)
**BRYSSELPARASITERA**.... [.......](mp3/bryssel_vv.mp3) ![](bilder/mp3.jpg)
![](bilder/mp3.jpg)
**MR EURO**................................................. [.......](mp3/mr_euro.mp3) ![](bilder/mp3.jpg)
![](bilder/mp3.jpg)
Jørn
Simen Øverli (Norge) -
**Unionsvise
**................. [........](mp3/01_Unionsvise.mp3) ![](bilder/mp3.jpg)
![](bilder/mp3.jpg)
**En EU-soldat** ![](bilder/mp3.jpg)
![](bilder/mp3.jpg)
Lyssna genom att klicka på
eller ladda ner genom att högerklicka och Spara mål som...


markdown:
**Cloud Của Tui có gì hot?**
- Thêm Bài hát/Playlist yêu thích vào Cloud.
- Tạo Playlist riêng theo sở thích âm nhạc.
- Tự động đồng bộ nếu sử dụng một tài khoản Cloud cho nhiều thiết bị.
- Nghe nhạc Offline dễ dàng mà không sợ phải tìm kiếm Playlist để tải lại nếu thay đổi thiết bị.

Set-Cookie: NCTNPLS=098053171ea01d45515d28a38204d51c;Path=/;Domain=.nhaccuatui.com;Expires=Thu, 20-Nov-2014 10:35:50 GMT;HttpOnly

P3P: CP='NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM'

Server: nginx+


Set-Cookie: NCTNPLS=88f000276ace9b5657ba6404e0246792;Path=/;Domain=.nhaccuatui.com;Expires=Thu, 20-Nov-2014 10:41:59 GMT;HttpOnly


markdown:
**Cloud Của Tui có gì hot?**
- Thêm Bài hát/Playlist yêu thích vào Cloud.
- Tạo Playlist riêng theo sở thích âm nhạc.
- Tự động đồng bộ nếu sử dụng một tài khoản Cloud cho nhiều thiết bị.
- Nghe nhạc Offline dễ dàng mà không sợ phải tìm kiếm Playlist để tải lại nếu thay đổi thiết bị.
## Bình Luận

Set-Cookie: NCT_TVC_ADV=605_1094;Path=/;Domain=.nhaccuatui.com;Expires=Tue, 21-Oct-2014 16:59:59 GMT;HttpOnly


markdown:
|
|![]()
|
|![]()
![]()
PARA DIFUSIÓN INMEDIATA
PR- 427-07
25 de noviembre de 2007
EN DISCURSO SEMANAL POR RADIO, EL ALCALDE BLOOMBERG ANUNCIA NUEVAS MANERAS EN QUE LOS NEOYORQUINOS PUEDEN CONSEGUIR INFORMACIÓN SOBRE COMEDORES PÚBLICOS Y BANCOS DE ALIMENTOS DE EMERGENCIA
A continuación se presenta el texto del discurso semanal del alcalde Bloomberg, preparado para su transmisión radial a través de 1010 WINS News Radio el domingo 25 de noviembre de 2007
“Buenos días. Les habla el alcalde Bloomberg.
“Sencillamente, no hay lugar para el hambre o la malnutrición en la ciudad más grande del mundo. Es por eso que, cada día, organizaciones religiosas, grupos comunitarios y hombres y mujeres de buena voluntad trabajan arduamente para aliviar el hambre en Nueva York. Lo mismo hace nuestro Gobierno local; déjenme hablarles sobre dos nuevos pasos que hemos dado para ayudar a los neoyorquinos necesitados a alimentar a sus familias.
“Primero, hemos asignado inmediatamente $1 millón extra a más de 500 comedores públicos y despensas de alimentos de emergencia en toda la ciudad. Estas organizaciones comunitarias proveen comida mensualmente a casi 900,000 neoyorquinos. Estamos inyectando más fondos a estos programas ahora porque sus gastos han aumentado. En parte se debe a la inflación; además porque estos programas han empezado a almacenar más alimentos nutritivos que cuestan un poquito más. El resultado: El dinero para alimentos de emergencia de hoy solo compra cerca de 80% de los alimentos que compraba hace cuatro años.
“El dinero extra que ahora estamos proveyendo al ‘Programa de Asistencia Alimenticia de Emergencia’ municipal comprará cerca de 1.3 millones de libras de comidas enlatadas u otros ingredientes alimenticios. En realidad estos fondos provienen del Gobierno federal. Son parte de un paquete de bonos que la Ciudad se ha ganado por mejorar nuestra administración del Programa de Cupones Alimenticios. Durante los últimos cuatro años, hemos hecho nuestro proceso de solicitud de cupones más simple y más conveniente, y también hemos reducido en gran medida el fraude y abuso. Debido a esas reformas, ahora podemos realizar esta inversión importante en nuestros comedores públicos y despensas de alimentos.
“También estamos mejorando la forma en que los neoyorquinos se informan sobre dónde y cómo pueden obtener alimentos de emergencia. En el pasado, cuando la gente llamaba al 311 con peticiones similares, eran conectados a un sistema de información automatizado. Y aunque todavía hay un sistema automatizado las 24 horas y 7 días a la semana, ahora las llamadas de alimentos de emergencia que son hechas de lunes a viernes (de 7:00 a.m. a 7:00 p.m.) y los sábados (de 7:00 a.m. a 3:00 p.m.) también pueden ser respondidas por operadores especialmente adiestrados. Ellos hablan con las personas que llaman sobre sus necesidades particulares, y les dicen sobre los lugares y horarios de los programas convenientes de alimentos de emergencia. Después de todo, cuando la nevera de una persona está vacía, hablar con un ser humano compasivo significa mucho.
“De hecho, la compasión humana básica estimula todo lo que hacemos para borrar el hambre en Nueva York, desde proveer más de 850,000 comidas nutritivas gratis o de bajo costo a estudiantes cada día escolar, hasta aumentar la aceptación de tarjetas de beneficio de cupones de alimentos en mercados verdes locales. Es también la razón por la que los Más Valientes y Más Distinguidos de Nueva York están una vez más participando en la recolección de alimentos enlatados de la temporada anual de fiestas.
“Ustedes también pueden unirse. Hasta el 4 de enero, por favor donen artículos alimenticios no perecederos en cualquier estación de bomberos o de policía. Ellos irán a City Harvest, un magnífico grupo sin fines de lucro con el que laboramos durante todo el año para suplir los programas de alimentos de emergencia de Nueva York. Y llamen al 311 para averiguar cómo pueden ser voluntarios en la lucha contra el hambre. Es una gran manera de retribuir a nuestra ciudad, y de mantener vivo el verdadero espíritu de la temporada de fiestas.
“Les habló el alcalde Mike Bloomberg. Gracias por su atención”.
![]()
CONTACTO PARA LOS MEDIOS DE DIFUSIÓN:
Stu Loeser (212) 788-2958
|
|![]()
|
|![]()
|
|![]()
![]()
![]()
![]()
|
|![]()


markdown:
|
|
|
|
Mới là tháng đầu tiên của quí 4, nhưng có thể thấy lịch 2012 đã được bày bán ở nhiều tuyến phố của Hà Nội. Đây cũng là năm đầu...
Thời gian gần đây, thị trường Trang sức vàng bạc Đá quý đã xuất hiện một cái tên mà chỉ nghe đã thấy sự hấp dẫn, nao nức khiến nhiều...
Kết thúc phiên giao dịch đêm qua (21/10), giá xăng kỳ hạn tháng 11 tăng 1 xu, tương ứng 0,3%, lên 2,69 USD/gallon. Tuy nhiên, tính chung cả tuần, giá...
Ngày nay, các loại sữa bột được tăng cường các dưỡng chất giúp trẻ phát triển toàn diện từ thể chất đến trí não không còn xa lạ. Tuy nhiên,...
Chưa bao giờ thế giới lại phải đối mặt với nhiều bất ổn về an ninh lương thực như hiện nay. Mưa bão, lũ lụt đang gây ra sự thiếu...

P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

Cache-Control: post-check=0, pre-check=0

Set-Cookie: ja_sanidineii_light_tpl=ja_sanidineii_light; expires=Sun, 11-Oct-2015 10:15:04 GMT; Max-Age=30672000; path=/


markdown:
Trang chủ
Tổng hợp phim
Phim lẻ
Phim lẻ mới
Phim bộ
Phim dài tập
Xem Phim khmer
khmer, Xem online khmer, Xem phim khmer, Phim khmer
BẠN ĐÃ XEM CHƯA
Cô Gái Với Hình...
Xem:
2,203
Loading ...
Kẻ Xuyên Không
Xem:
2,236
Loading ...
Đảo Ngọc huyền...
Xem:
422
Loading ...
Chuột và Mèo
Xem:
1,175
Loading ...
Sinh Ra Để Đua
Xem:
1,937
Loading ...
Hãy Nhớ
Xem:
935
Loading ...
Mình Cưới Thật...
Xem:
13,093
Loading ...
Chiến Binh Vũ...
Xem:
988
Loading ...
Danh Sách Phim Lẻ
Phim Chiếu Rạp
Phim Hài Hước
Phim Hành Động
Phim Kinh Dị
Phim Phiêu Lưu
Phim Tâm Lý
Phim Thần Thoại
Phim Thể Thao
Phim Tình cảm
Phim Viễn Tưởng
Phim Võ Thuật
Danh Sách Phim Bộ
Phim Bộ Hàn Quốc
Phim Bộ Hong kong
Phim Bộ Mỹ
Phim Bộ Việt Nam
Phim Bộ Đài Loan
Phim Đang Chiếu Hot
Đôi Cánh Đồng Tiền
Mình Cưới Thật Em Nhé
Hoa Cúc Xanh
Bước Qua Bóng Tối
Ngôi sao thứ 31
Hãy Hái Sao Cho Em
Danh Y Vượt Thời Gian
Thám Tử Lừng Danh Conan
Hoàng Tử Gác Mái
Phẩm Chất Quý Ông
Bằng Chứng Thép Phần 3
Bí Mật Của Tình Yêu
Song Long Đại Đường
Nhất Đen Nhì Đỏ
Nhất Đen Nhì Đỏ 2
Phim mới đăng tải
Thần y Hỷ Lai Lạc
Nguyên soái vui vẻ
Bình Tây Đại nguyên soái
Mỹ nhân vô lệ
Viện dệt hoàng cung
khmer
,
xem phim quan huy
,
van menh thanh trieu
,
hanh phuc co
,
hai ch em
,
táº¥m lã²ng cha máº¹ táºp 147
,
x mne
,
cha chã¡â»â€œng con dã£â¢u
,
thã¡âºâ¥t giã¡â»â€ºi truyã¡â» n thuyã¡âºâ¿t
,
phim sex nhat ky vang anh
,
phi phu de
,
盲钬樏て抧gth谩潞拢ohoa th忙掳谩禄拢ng
,
phim cam 18 tuoi
,
yã£âªu ngã¦â°ã¡â» i giã£âºp viã¡â»â€¡c
,
em hứng
,
thuyethuyetdaiky
,
trungnguenkiemkhach
,
tien hat than tram
,
co hang com
,
phim sexy gay boy
Xem phim online by:
SharePhim.Net
Xem phim online


markdown:
SIEUTHINHANH
|
TRANG CHل»¦
|
GIل»ڑI THIل»†U
|
Sل؛¢N PHل؛¨M
|
LIأٹN Hل»†
ؤگؤƒng nhل؛p
ؤگل»“ chئ،i أ”tأ´
» Chل»‘ng nأ³ng
» Phim dأ،n kأnh
SP Nhأ hأ ng, K/sل؛،n
» SP cho Khأ،ch sل؛،n
» Thiل؛؟t bل»‹ nل»™i thل؛¥t
Chل»چn lل»±a thأھm tل؛،i
cأ،c webshop khأ،c :
SNOWHA
CONHEOVANG
ANBINHTOURSHOP
XULYNUOCNHIEM
OZONELINO
PHIMCACHNHIET
MAYDONVESINH
BONSAI
XULYMOITRUONG
HAITHANHFOOD
Phim chل»‘ng nأ³ng أ´tأ´ chل؛¥t lئ°ل»£ng cao
1.950.000
ؤ‘/Xe
Chi tiل؛؟t
|
Chل»چn mua
أ´ tأ´ & biل»‡n phأ،p chل»‘ng nأ³ng أ´tأ´
1.950.000
ؤ‘/Xe
Chi tiل؛؟t
|
Chل»چn mua
Chuyأھn lل؛¯p ؤ‘ل؛·t phim cأ،ch nhiل»‡t أ´tأ´
1.950.000
ؤ‘/Xe
Chi tiل؛؟t
|
Chل»چn mua
Biل»‡n phأ،p chل»‘ng nأ³ng أ´tأ´
1.950.000
ؤ‘/Chiec
Chi tiل؛؟t
|
Chل»چn mua
Kأnh vؤƒn phأ²ng, nhأ & biل»‡n phأ،p chل»‘ng nأ³ng
150.000
ؤ‘/M2
Chi tiل؛؟t
|
Chل»چn mua
Giل»›i thiل»‡u phim dأ،n kinh أ´tأ´
1.950.000
ؤ‘/Xe
Chi tiل؛؟t
|
Chل»چn mua
Phone:
(08).3848.0654
Email:
sales@sieuthinhanh.com

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0


markdown:
Trang chủ » Tin tức - Sự kiện » Tin chuyên ngành » Chuyện vui
Quy định mới | Bài tư vấn | Nghiên cứu - Khảo sát
Đọc và hiểu được ngôn ngữ cử chỉ là yếu tố quan trọng để phỏng vấn thành công. Hình thức giao tiếp phi ngôn ngữ này sẽ giúp bạn biết được người phỏng vấn đang nghĩ gì, nhờ vậy bạn có thể tự điều chỉnh những ngôn ngữ cử chỉ của bản thân sao cho phù hợp và chiếm được cảm tình của Nhà tuyển dụng (NTD). Và tất nhiên cuối cùng là để có được công việc bạn mong muốn!
1. “Cá ươn” hay “nghiền xương”?
Cách bắt tay nói lên nhiều điều về tính cách chúng ta. Bạn bắt tay nhẹ nhàng? Hay bạn bóp chặt tay người ta như thể muốn “nghiền xương” họ? Những người năng nổ thường bắt tay một cách mạnh mẽ còn những người có lòng tự tôn thấp thường bắt tay một cách ẻo lả, theo kiểu “cá ươn.
Một cái tay bắt tay đúng là sẽ gồm 3 bước:
- Bảo đảm móng tay của bạn được cắt ngắn và sạch sẽ.
- Bảo đảm bàn tay ấm, không có mồ hôi.
- Bắt tay một cách chuyên nghiệp và lịch sự, với một cái nắm chắc chắn và nụ cười ấm áp.
2. Sức mạnh của “cửa sổ tâm hồn”
Thông thường, giao tiếp bằng mắt với tỷ lệ 60% là một con số an toàn, vừa đủ để làm NTD có cảm tình với bạn. Nếu nhiều hơn, bạn trông có vẻ căng thẳng; nếu ít hơn, bạn có nguy cơ bị đánh giá là hờ hững với những gì NTD đang nói. Tuy nhiên, điều bạn cần lưu ý nhất khi giao tiếp bằng mắt chính là sự tự nhiên, tùy theo lời nói, cảm xúc mà có nhu cầu giao tiếp bằng mắt hay không. Nếu bạn bị ám ảnh là phải giao tiếp bằng mắt với NTD để rồi cứ nhìn chằm chằm vào họ thì sẽ khiến họ cảm thấy khó chịu.
Khi gặp người phỏng vấn, bạn hãy nhìn thẳng vào mắt họ và nhủ thầm, “Ôi, thật tuyệt khi cuối cùng cũng được gặp ông (bà)!”. Ý nghĩ này sẽ khiến bạn mỉm cười và NTD sẽ chú ý ngay đến tâm trạng vui vẻ của bạn. Khi chúng ta nhìn một người mình thích, đồng tử của chúng ta thường giãn ra và người đối diện sẽ dễ dàng nhận thấy điều này.
Trong suốt cuộc phỏng vấn, hãy tập trung hướng cái nhìn của bạn vào vùng tam giác ngược với 3 đỉnh là lông mày trái, mũi và lông mày phải trên khuôn mặt của người đối diện.
Lưu ý là bạn đừng nhìn chòng chọc vào môi người đối diện vì như thế sẽ bị xem là quấy rối. Còn nếu bạn nhìn vào trán thì người ta có thể nghĩ là bạn đang xem thường họ.
3. Đúng tư thế, tăng tự tin
Tư thế là một “vũ khí” quan trọng bạn cần sử dụng thành thạo trong lúc phỏng vấn. Tư thế đúng mực sẽ giúp bạn gia tăng sự tự tin. Nếu bạn cảm thấy hơi mệt mỏi, hãy chú ý cách bạn ngồi hoặc đi đứng. Rất có thể bạn đang ngồi thượt ra hay đi với vai thõng xuống. Dáng đi hoặc ngồi như thế sẽ chèn ép lồng ngực và hơi thở, khiến bạn cảm thấy lo lắng hoặc không thoải mái.
4. Hãy linh hoạt điều khiển đầu của bạn!
Nếu bạn muốn cảm thấy tự tin trong lúc phỏng vấn, hãy giữ đầu của bạn cân bằng. Tư thế này cũng thích hợp khi NTD đang lắng nghe và quan sát bạn. Ngược lại, khi muốn tỏ ra thân thiện và cho người đối thoại thấy bạn đang chú ý lắng nghe, tiếp nhận thông tin; hãy hơi nghiêng đầu bạn sang một bên và thi thoảng gật gù.
5. Kiểm soát đôi tay
Đôi tay có thể giúp bạn thể hiện sự cởi mở, vì thế hãy buông hờ cánh tay sát với thân người, đôi tay đặt trên đùi bạn, đừng thả lỏng quá mà cũng đừng gồng - nắm chặt quá. Tư thế tay vừa phải như vậy cho thấy bạn luôn điềm tĩnh và tự tin.
Những người trầm tính thường ít cử động cánh tay ra xa cơ thể hơn những người cởi mở. Bạn đừng vung tay vung chân quá nhiều khi nói, nếu không NTD sẽ nghĩ bạn quá bốc đồng, không thể kiểm soát được hành vi của mình. Tuyệt đối tránh việc khoanh tay trong lúc phỏng vấn.
Sau đây là 2 cách thường dùng để đánh giá về cử chỉ của tay:
- Bàn tay hơi ngửa lên và hướng ra ngoài: tính tình thân thiện và cởi mở
- Bàn tay úp xuống: có khả năng tạo ảnh hưởng và tính tình năng nổ.
6. Giữ yên đôi chân
Chân chúng ta thường di chuyển nhiều hơn bình thường khi chúng ta bối rối, căng thẳng hoặc có điều gì muốn che giấu. Vì thế, bạn cần cố gắng giữ yên chúng trong lúc phỏng vấn, với khoảng cách vừa phải giữa hai chân, không khép quá (với nam) cũng không giang rộng quá. Bạn không nên bắt chéo chân vì nó sẽ tạo ra một sự ngăn cách giữa bạn và người phỏng vấn và có thể làm bạn khó ngồi yên. Truyệt đối tránh trường hợp vắt mắt cá chân này lên đầu gối chân kia, vì chân bạn sẽ tạo thành hình “số 4” ngông nghênh rất khó coi, dễ tạo phản cảm.
Gửi bình luận của bạn
(Bấm
vào đây để nhận mã)
Các
bài mới:
Các tin đã đưa
ngày :
Giới Thiệu Smart Train
Đội Ngũ Giảng Viên
Cơ Sở Vật Chất
Đăng Ký Học Thử
Đăng Ký Thi CBE
Thi Thử CBE
xem các hình ảnh sự kiện
khác
xem các video clip khác
EMAIL:
info@smarttrain.edu.vn
© 2014 Bản quyền của
Smart Train | www.smarttrain.edu.vn | Sitemap
HOTLINE:
(08) 3931 3333 – Ext: 10
Gửi bình luận của bạn


markdown:
MAC
Tin tức
Mới cập nhật
Mới cập nhật
Download nhiều
Tin công nghệ
Danh mục phần mềm
Tin công nghệ
iTunes 11.4 (32-bit)
Apple Inc - 106.2 MB ( Freeware )
Audio and Videos
Tên phần mềm
iTunes 11.4 (32-bit)
Tên file
itunessetup.exe
Kích thước
106.2 MB
Yêu cầu hệ thống
Windows
Bản quyền
Freeware
Nhà cung cấp
Apple Inc
Website
http://www.apple.com/itunes
Dung lượng
106.2 MB
DOWNLOAD
Click nút Like (Thích) để bắt đầu Download
( Nếu đã Like mà nút không thấy nút DOWNLOAD, vui lòng bấm
vào đây
)
Nếu bạn đã bấm Like rồi truớc đây rồi và giờ không hiện nút Download thì bạn vui lòng rê chuột lại vào nút Like và bấm Unlike, sau đó refresh trình duyệt và bấm Like 1 lần lại để hiện nút Download nhé.
50,353 lượt download
iTunes là một âm thanh cho máy nghe nhạc, vui chơi và tổ chức các tệp nhạc kỹ thuật số, và mua nhạc kỹ thuật số tác phẩm trong các FairPlay quyền quản lý kỹ thuật số định dạng. The iTunes Store Âm nhạc là một phần không thể thiếu của iTunes mà qua đó người dùng có thể mua nhạc kỹ thuật số tập tin từ bên trong iTunes.
Người dùng có thể để tổ chức các âm nhạc của họ vào danh sách nhạc, chỉnh sửa tập tin thông tin, hồ sơ về Cty đĩa, sao chép tập tin vào một máy nghe nhạc kỹ thuật số âm thanh, mua bán âm nhạc trên Internet thông qua các-xây dựng trong cửa hàng âm nhạc, hãy chạy một visualizer để hiển thị các hiệu ứng đồ họa trong thời gian tới âm nhạc, cũng như mã hóa âm nhạc vào một số các định dạng âm thanh khác nhau.
iTunes Quicktime Player bao gồm các cài đặt.
Các phần mềm cùng loại
Các phần mềm mới cập nhật
Quintessential Player 4.51
2.3 MB
( Freeware )
H-PC TV Online Version 3.0
2.6 MB
( Freeware )
jetAudio 8.1.2 Basic
37.2 MB
( Freeware )
Media Player Classic 6.4.9.1
1.10 MB
( Open Source )
Songbird 1.0.0
11.8 MB
( Freeware )
iTunes 11.4 (32-bit)
106.2 MB
( Freeware )
SuperAntiSpyware 6.0.1158
18.8 MB
( Freeware )
uTorrent 3.4.2 Build 34537
1.9 MB
( Freeware )
FrostWire 5.7.7
23.2 MB
( Freeware )
Firefox 33.0 Beta 9
34.8 MB
( Freeware )
BitTorrent 7.9.2 Build 34543
1.9 MB
( Freeware )
Photoscape 3.7
20.4 MB
( Freeware )
Nhiều lựa chọn smartphone tầm trung giá tốt tại Việt Nam
Nhóm smartphone tầm trung hiện chủ yếu bị thống trị bởi những model cao cấp đời cũ đã giảm giá với thiết kế đẹp,...
Apple đưa iOS lên 8.1, cho gửi tin nhắn của iPhone trên máy tính
Phiên bản cập nhật mới nhất của hệ điều hành iOS 8 còn bổ sung kho lưu trữ đám mây iCloud Drive hay tùy chọn dùng mạng...
Vì sao Apple tuyệt đối không bán iPhone ở một số quốc gia?
Có thêm 36 quốc gia nữa sẽ bán iPhone 6 của Apple trong tháng 10 này, và đến cuối năm sẽ có trên 115 quốc gia chính thức...
4 ứng dụng hỗ trợ quản lý pin dành cho Android
Pin của các thiết bị cầm tay luôn là điều được người dùng quan tâm, nhất là đối với các smartphone và máy tính bảng...
Lumia 925 giảm giá còn 6,5 triệu đồng
Chiếc điện thoại một thời được xem là đẹp nhất trong dòng Lumia hiện có giá bán chỉ ngang với một số smartphone...
Những smartphone đầu tiên được nâng cấp lên Android 5.0 Lollipop
Mỗi một phiên bản Android mới được ra mắt, vấn đề được nhiều người quan tâm chính là thời điểm thiết...
Xuất hiện tin đồn Lenovo thâu tóm BlackBerry trong tuần này
Theo một nguồn tin từ trang Benzinga.com, Lenovo có thể sẽ công bố thương vụ mua lại hãng di động Canada trong tuần...
Macbook Air có nên nâng cấp lên OS X 10.10 Yosemite?
Máy tính của mình là MacBook Air 2012, RAM 4GB thì không biết có nên nâng cấp lên hệ điều hành OS X 10.10 Yosemite vừa...
Phát hiện cỗ xe ngựa có niên đại lên tới 2200 năm tuổi
Mới đây, các nhà khảo cổ đã phát hiện và khai quật thành công cỗ xe ngựa cùng một loạt các phụ kiện cho xe...
Lumia 925 giảm giá còn 6,5 triệu đồng
Chiếc điện thoại một thời được xem là đẹp nhất trong dòng Lumia hiện có giá bán chỉ ngang với một số smartphone...
Motorola Droid Turbo pin khủng lộ ảnh trước khi ra mắt
Chiếc điện thoại của Motorola có cấu hình mạnh với chip Snapdragon 805 hỗ trợ màn hình 2K.
Leica X phiên bản thời trang có giá gần 3.000 USD
Leica X Edition Moncler nổi bật với lớp vỏ da cao cấp với điểm nhấn là sọc ba màu xanh, trắng và đỏ, đặc trưng của...
Trang chủ
Tin tức
Giới thiệu
Điều khoản sử dụng
Mới cập nhật
Các sản phẩm khác của
HuyIT.com
HuyIT.com
HenryHuy.com
LOFWI.com
CuoiDuKieu.com
FontDep.com
TinSotDeo.com
HatDauBe.com
CuaSoTamHon.net
© 2008 - 2014
Soft4IT
.com - một sản phẩm của
HuyIT.com
phát triển bởi
LOFWI

Server: Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.3.29


markdown:
Cách làm mức dừa ngon cho ngày tết nguyên đán rất dễ và đơn giản. các bạn xem hướng dẫn dưới đây nha!
- 600g đường
- 1 thìa cà phê tinh chất vani
Rửa thật sạch dừa đã nạo sao cho đảm bảo dừa hết dầu. Bạn kiểm tra bằng cách xem nước rửa, ban đầu nước rửa dừa có màu trắng đục.
Rửa đến khi nước trong, không có dầu là được.
Dừa vớt ra, để ráo.
Đến bước này bạn cân lại cùi dừa, cứ 1kg cùi dừa bạn ướp với 600g đường.
Sau khoảng 8 tiếng đường sẽ tan bớt và dừa ngót bớt, bạn dùng đũa đảo đều cho dừa ngấm đều và đường tan hết. Tổng thời gian ướp khoảng từ 12 - 14 tiếng, đến khi bạn nhìn thấy các sợi dừa trong.
Dùng chảo rộng, có đáy dày để sên dừa. Cho dừa & nước đường vào chảo, ban đầu bạn có thể để lửa to, đến khi nước đường sôi bạn chuyển lửa nhỏ, đảo đều dừa liên tục.
Với 1kg dừa, bạn nên sên làm 2 mẻ, không nên sên quá nhiều dừa trong chảo sẽ khó đảo và dễ làm cháy mứt.
Đến khi nước đường gần cạn thì cho tinh chất vani vào đảo đều.
Từ đây bạn nên dùng 2 đôi đũa, đảo xóc dừa liên tục...
... đến khi đường khô lại thành dạng hạt li ti thì tắt bếp...
... cho dừa ra mâm, xóc đều và để mứt nguội là xong.
Có thể nói, mứt dừa là món mứt phổ biến nhất trong ngày tết cổ truyền ở Việt Nam.
Chúc các bạn thành công với món mứt dừa tết cổ truyền
##
### Nguyên liệu làm mức dừa tết:- 1kg cùi dừa
- 600g đường
- 1 thìa cà phê tinh chất vani
### Cách làm mức dừa cho ngày tết nguyên đán:Dừa chọn loại bánh tẻ, gọt bỏ lớp vỏ lụa, dùng dụng cụ nạo nạo theo vòng tròn để được sợi dừa dài.
Rửa thật sạch dừa đã nạo sao cho đảm bảo dừa hết dầu. Bạn kiểm tra bằng cách xem nước rửa, ban đầu nước rửa dừa có màu trắng đục.
Rửa đến khi nước trong, không có dầu là được.
Dừa vớt ra, để ráo.
Đến bước này bạn cân lại cùi dừa, cứ 1kg cùi dừa bạn ướp với 600g đường.
Sau khoảng 8 tiếng đường sẽ tan bớt và dừa ngót bớt, bạn dùng đũa đảo đều cho dừa ngấm đều và đường tan hết. Tổng thời gian ướp khoảng từ 12 - 14 tiếng, đến khi bạn nhìn thấy các sợi dừa trong.
Dùng chảo rộng, có đáy dày để sên dừa. Cho dừa & nước đường vào chảo, ban đầu bạn có thể để lửa to, đến khi nước đường sôi bạn chuyển lửa nhỏ, đảo đều dừa liên tục.
Với 1kg dừa, bạn nên sên làm 2 mẻ, không nên sên quá nhiều dừa trong chảo sẽ khó đảo và dễ làm cháy mứt.
Đến khi nước đường gần cạn thì cho tinh chất vani vào đảo đều.
Từ đây bạn nên dùng 2 đôi đũa, đảo xóc dừa liên tục...
... đến khi đường khô lại thành dạng hạt li ti thì tắt bếp...
... cho dừa ra mâm, xóc đều và để mứt nguội là xong.
Có thể nói, mứt dừa là món mứt phổ biến nhất trong ngày tết cổ truyền ở Việt Nam.
Chúc các bạn thành công với món mứt dừa tết cổ truyền
## 0 comments:
## Đăng nhận xét


markdown:
#
Mary Lou Jepsen:
Liệu trong tương lai, ta có thể đọc hình ảnh từ não bộ?
Là chuyên gia hàng đầu trong lĩnh vực hiển thị kĩ thuật số, Mary Lou Jepsen tiến hành nghiên cứu cách thể hiện trên máy tính những ý tưởng sáng tạo từ não bộ. Từng là một bệnh nhân được phẫu thuật não, cô khao khát biết thêm về hoạt động thần kinh ẩn sau các phát minh, sáng tạo và suy nghĩ. Dung hòa hai niềm đam mê này cùng với hai nghiên cứu não bộ nổi trội, Mary Lou chỉ ra một tầm cao mới trong nghiêu cứu và thấu hiểu tư duy con người.
-
Similar topics
-
[Ted conference](/topics/ted+conference)
-
[Brain](/topics/brain)
-
[Creativity](/topics/creativity)
-
[Neuroscience](/topics/neuroscience)
-
[Science](/topics/science)
This talk was presented at an official TED conference, and was featured by our editors on the home page.
### Related talks
### Discuss
81 comments
Enthusiastically agree? Respectfully beg to differ? Have your say here.
Please log in or sign up to add comments.
Sort comments by
There are currently no comments for this talk.
Show more comments

Cache-Control: s-maxage=30, max-age=0, public=true

Via: 1.1 varnish


markdown:
Đến nay, kích thước của Samsung Galaxy Note II được xem là chủ đề bàn tán nhiều nhất. Một số nguồn tin rò rỉ cho biết màn hình 5.3 inches của Samsung Galaxy sẽ “khủng” hơn khi tiếp tục được nâng cấp lên mức 5.5 inches ở Samsung Galaxy Note II.
Dù chưa hề có thông tin chính thức về kích thước của Galaxy Note thế hệ hai này, nhưng cộng đồng hi-tech đã nhanh chóng đưa ra những bản vẽ mô phỏng theo dự đoán của mình. Điều này chỉ khiến cho làng công nghệ trở nên nóng lòng hơn.
Thiết kế mô phỏng về Samsung Galaxy Note II với màn hình 5.5 inches và camera 12 megapixel - Ảnh slashgear
Một tin đồn khác được lan truyền mạnh mẽ trong thời gian gần đây khi trang GL Benmark vừa công bố một loại Android lạ mang mã hiệu Samsung GT-N7100.
Thông tin cho thấy chiếc Android này được chạy trên chip lõi tứ Exynos 4412 với tốc độ 1.6Ghz, đồ họa Mali-400. Mặt khác, tên mã GT-N7100 khá tương đồng với mã GT-N7000 đang chạy trên Note đời đầu càng khiến cho những dự đoán đều nhắm tới đó chính là Galaxy Note II.
Mã GT-7100 là của dòng sản phẩm mới nào của Samsung? - Ảnh techspot
Gắn liền với tin đồn về cấu hình “khủng”, S-Pen của Samsung Galaxy Note II cũng khiến nhiều người xôn xao. Điều này cũng hoàn toàn dễ hiểu bởi công nghệ Wacom được tích hợp vào Galaxy Note đời đầu và Samsung Nexus đã trở thành vũ khí sắc bén của Samsung khi cạnh tranh với các hãng khác.
Theo thông tin rò rỉ từ http://www.patentbolt.com, chiếc S-Pen mới không chỉ được hoàn thiện công nghệ nhận diện nhiều lực nhấn để có thể viết, vẽ đa dạng, mà sắp tới, S-Pen còn được tích hợp wireless headset giúp người dùng có thể thoại một cách nhanh chóng và tiện lợi như một tai nghe Bluetooth.
Phác thảo bị rò rỉ này là S-Pen của Note II? - Ảnh patentbolt
Trước những bàn tán xôn xao về chiếc Samsung Galaxy Note II, người phát ngôn của Samsung vẫn im lặng trước những thắc mắc về cấu hình.
Đầu tháng 3.2012, nhà sản xuất smartphone hàng đầu thế giới này đã tiết lộ trên Reuteurs về thời điểm ra mắt của Samsung Galaxy Note II là ngày 29.08.2012 tại IFA, Đức. Nếu tiết lộ này hoàn toàn chính xác thì quả thật Samsung đang dần chiếm thế tiên phong trước Apple, khi mà thông tin chính thức ra mắt iPhone 5 liên tục bị trì hoãn.
Cùng với Samsung Galaxy SIII được ra mắt vào tháng 6 và Samsung Galaxy Note II vào cuối tháng 8, đây có thể được xem là như một cú chiến thắng đúp đầy ngoạn mục của Samsung ở thị trường toàn cầu và Việt Nam trước các đại gia di động khác.
Dù vẫn chỉ là đồn đoán, nhưng hơn bao giờ hết, cộng đồng người hâm mộ đang dõi theo nhất cử nhất động của Galaxy Note II khi ngày ra mắt chính thức 29.8 đang đến rất gần. Fan của iPhone có lẽ ngày càng sốt ruột hơn khi Samsung liên tục tung ra thị trường những dòng sản phẩm mới với thiết kế và tính năng đột phá mà Apple dường như vẫn im lặng và chậm chạp trong việc cải tiến sản phẩm của mình.
THÔNG TIN DỊCH VỤ
Tin tức Thanh Niên Online
Tin sao iHay
Tin nóng
Tin thể thao
Sài Gòn Ẩm Thực
World Cup 2014
Tổng biên tập: NGUYỄN QUANG THÔNG
Phó tổng biên tập phụ trách Thanh Niên Online: HẢI THÀNH
Phụ trách tòa soạn Thanh Niên Online:
- Ủy viên Ban biên tập - Tổng Thư ký tòa soạn: TRẦN VIỆT HƯNG
- Ủy viên Ban biên tập - Phó tổng Thư ký tòa soạn: ĐÀO HỒNG HẠNH
- Phó tổng Thư ký tòa soạn: ĐỖ HÙNG
- Thư ký tòa soạn: NGUYỄN MINH GIAO - NGUYỄN ĐÌNH HUÂN
NGUYỄN XUÂN TOÀN - NGUYỄN TRẦN DUY
Giấy phép xuất bản số 298/GP - BTTTT cấp ngày 29.7.2013
© 2003-2013 Bản quyền thuộc về Báo Thanh Niên
Cấm sao chép dưới mọi hình thức nếu không có sự chấp thuận bằng văn bản
Hotline: Quảng cáo, PR - 0908 78 0404
Thanh Niên Online chạy tốt nhất trên các trình duyệt
Internet Explorer 8.0 trở lên
Firefox 6.0 trở lên
Chrome 14.0 trở lên

X-MS-InvokeApp: 1; RequireReadOnly

Cache-Control: public, s-maxage=600, max-age=600


markdown:
(TNO) Mặc dù Chủ tịch UBND TP.Hà Nội Nguyễn Thế Thảo đã gửi văn bản chỉ đạo đóng cửa các hoạt động kinh doanh, sửa chữa tại khu Zone 9 nhưng hiện tại mọi hoạt động ở đây vẫn diễn ra bình thường.
Tin tức Thanh Niên Online
Tin sao iHay
Tin nóng
Tin thể thao
Sài Gòn Ẩm Thực
World Cup 2014
Tổng biên tập: NGUYỄN QUANG THÔNG
Phó tổng biên tập phụ trách Thanh Niên Online: HẢI THÀNH
Phụ trách tòa soạn Thanh Niên Online:
- Ủy viên Ban biên tập - Tổng Thư ký tòa soạn: TRẦN VIỆT HƯNG
- Ủy viên Ban biên tập - Phó tổng Thư ký tòa soạn: ĐÀO HỒNG HẠNH
- Phó tổng Thư ký tòa soạn: ĐỖ HÙNG
- Thư ký tòa soạn: NGUYỄN MINH GIAO - NGUYỄN ĐÌNH HUÂN
NGUYỄN XUÂN TOÀN - NGUYỄN TRẦN DUY
Giấy phép xuất bản số 298/GP - BTTTT cấp ngày 29.7.2013
© 2003-2013 Bản quyền thuộc về Báo Thanh Niên
Cấm sao chép dưới mọi hình thức nếu không có sự chấp thuận bằng văn bản
Hotline: Quảng cáo, PR - 0908 78 0404
Thanh Niên Online chạy tốt nhất trên các trình duyệt
Internet Explorer 8.0 trở lên
Firefox 6.0 trở lên
Chrome 14.0 trở lên