Server-side Programming 杂记
COMP3322 课程 Server-side technologies 相关内容拾遗。
从 HTML, CSS, JavaScript (JQuery) 一路走来,我们接触的几乎都是 client-side technologies。接下来我们将完成 web technologies 的另一块拼图 — server-side technologies。
This article is a self-administered course note.
It will NOT cover any exam or assignment related content.
Server-side Programming
Server-side Programming 是 dynamic sites 的基础。
主角们分别是:
- Browser: 某个客户端主机。
- Web server: 某个服务器主机。
- File system: 服务器主机的 file system,存储 static resource 与 HTML template。
- Web application: 服务器主机搭载的各种程序 (任何 server-side codes),即本节所介绍的内容。
- Database: 某个数据库。
Client-side browser 与 Server 是如何进行交互的?
- Browser 向 server 发出 HTTP request。
- Server 将 request 中存储的信息 (URL, GET/POST data, Cookies) 作为输入执行 web applications。
- Web application 从 file system 中获取 HTML 模板,从 database 中获取对应的数据插入 HTML 模板的 placeholders 中生成 HTML page。
- Server 从 file system 中获取 static resource 进一步更新该 HTML page。
- Server 将该 HTML page 作为 HTTP response 对 browser 进行回应。
- Browser 执行本地的 applications (HTML, CSS, JavaScript;或进行 cross-site request) 再进一步更新该 HTML page。最后进行渲染并将该 HTML page 呈现在屏幕上。
PHP
PHP 是一种著名的 hypertext preprocessor。
我们基本可以将 .html
与 .php
视作同一种文件。
在 HTML/PHP 文件中,被 <?php
, ?>
标签包围的是 PHP code,在该标签外的是 HTML code。PHP code 可以镶嵌在
HTML code 中的任意一处,用法十分灵活。
需要注意的是,server 传递给 client 的 HTML/PHP 文件一定是由纯 HTML code 组成的。这是因为在生成 HTTP response 之前,server 将首先执行 HTML/PHP 文件中的所有 PHP code,再将生成的新 HTML/PHP 文件作为 response 发送给 client;这也是为什么 PHP 被称为 hypertext pre-processor。
PHP 是一种 dynamically typed language,其语法和 JavaScript 十分类似。
Variable Scope
PHP 中的变量以 $
开头。
- local scope: variables inside a function can be referenced solely in that function.
- global scope: variables outside a function can only be accessed outside a function.
- static scope: variable inside a function continues to exist after the function terminates.
唯一要注意的是 PHP
中的全局变量默认是不能在函数内部访问的;这和传统的
lexical scope 很不同。我们需要通过添加 global
关键字从函数内部访问全局变量。
1 |
|
另外,PHP 中所有函数的默认 scope 是 global scope。
- They can be called outside a function even if they were defined inside another function.
Arrays
PHP 中的 arrays 默认是 associative arrays。
- Array keys must be either integers or strings and need not be sequential.
- We keys are not explicitly defined, they are 0, 1, ...
1 | $array[0] = "Narukami Yu"; |
在这个例子中,理世将被添加到 $array[6]
中:这是因为 5
是最后一个确定的 numeral array index。
Superglobal Variables
Predefined assotiative arrays in PHP that can always be accessible, regardless of scope.
$_GET
: name/value pairs sent from the client with GET method.$_POST
: name/value pairs sent from the client with POST method.$_COOKIE
: cookie name/value pairs.$_SESSION
: session name/value pairs.$_REQUEST
: contents of$_GET
,$_POST
and$_COOKIE
.$_SERVER
MySQL & PHP Support
Relational DBMS (database management system)
- 行 (rows) 为 records。
- 每个 row 有若干个 columns;即每个 record 有若干个 fields。
- 每个 table 有至多一个 special field — primary key,用于 uniquely identify each record。
MySQL Command
使用 CREATE
创建一个 table:
1 | CREATE TABLE stdRecord ( |
MySQL 命令的 semantic meaning 很明显,因此不在此详细介绍。除
CREATE
之外的 keywords 还有:
INSERT
:插入新的 record。配合INTO
(table) 与VALUES
(value)。DELETE
:删除 record(s)。配合FROM
(table) 与WHERE
(key 或其他 fields)。SELECT
:提取 record(s)。配合FROM
(table) 与WHERE
(key 或其他 fields)。UPDATE
:更新 record(s)。配合SET
(需要更新的 fields) 与WHERE
(key 或其他 fields)。
PHP support for MySQL
第一步:opens a new connection to MySQL server. $conn
is
a connection object.
1 | define("DB_HOST", "mydb"); |
第二步,使用 mysqli_query()
执行指定的
query。$record
is a mysqli_result
object.
- successful
SELECT
,SHOW
,DESCRIBE
, orEXPLAIN
: return amysqli_result
object. - successful
DELETE
,UPDATE
: returnTRUE
. - failed query: return
FALSE
.
1 | $query = "SELECT * FROM stdRecord WHERE uid = '$user_id'"; |
第三步,对 mysqli_result
对象进行处理,提取数据。
1 | if (mysqli_num_rows($record) > 0) { |
第四步,free resources and close connections.
1 | mysqli_free_result($record); |
Cookies & Sessions
有点难搞的两个概念,花了挺久才彻底弄明白。
Cookies
一定要记住,cookies 是在 browser (client-side) 被存储与更新的。那么具体来说 cookies 是如何工作的呢?
Server-side (PHP application):
- 收到 browser 发送的 HTTP request。
- GET: 通常携带与
user_id
有关的 cookie。 - PUT/POST: 通常携带与 user preference 有关的 cookie。
- GET: 通常携带与
- PHP 端通过
$_COOKIE['cookie_name']
获取 request 中储存的 cookie。 - 根据获取的 cookie 执行相应的代码,生成 PHP/HTML 文件并作为 HTTP response 发回给 browser。
- 若 HTTP request 中没有携带 cookie (e.g.
!isset($_COOKIE['user_id'])
),(如需要) 将在 PHP 端生成对应的 cookies 作为 HTTP response 的一部分发回给 browser。- 具体来说,PHP 端通过
setcookie()
函数在 response 中添加Set-Cookie
header。
- 具体来说,PHP 端通过
Client-side (JavaScript application):
- 收到 server 发回的 HTTP response。
- browser 将 response 中的
Set-Cookie
header 指定的 cookies 存储在document.cookie
中。(一般来说,若 cookie expires,document.cookie
中对应的 cookie 将消失) - JavaScript 端能够访问或更改
document.cookie
。 - 此后所有对
/index.php
发起的 HTTP request,browser 都会自动将document.cookie
中存储的 cookies 作为 request 的一部分发送给 server。
为什么说 cookies 是 browser-maintained 的,答案就在于
document.cookie
。我之前一直以为其与 PHP 中的
$_COOKIE[]
起到的作用相同,但其实大相径庭。
document.cookie
存储在 browser 中。document.cookie
能被 PHP 端间接修改 (browser 根据 response 中的Set-Cookie
header 进行修改),也能被 JavaScript 端直接修改。document.cookie
将自动 (implicitly) 包含在 HTTP request (Cookie
header) 中。$_COOKIE[]
simply 是 server 接收到的 request 中的 cookie 信息的接口。对$_COOKIE[]
的修改是没有意义的 (因为这并不会影响到document.cookie
中存储的 cookies)。
Sessions
Sessions 本质上也是一种 cookies,只不过它在 PHP 端添加了对应的
authenticate 机制。PHP 端将 session id 存储在 $_SESSION[]
中以便进行 authentication。
- A session starts with the PHP
session_start()
function. - 与上述过程几乎一致。区别在于当 server 通过设置
$_SESSION[]
而不使用setcookie()
来操纵 session id。类似$_SESSION['sid'] = $sid
这样的 statements 有两个作用:- 将 session id 存储在
$_SESSION[]
中。 - 类似于
setcookie()
,将 session id 发回并指导 browser 将其存储在document.cookie
中。
- 将 session id 存储在
- server 收到 response 后,通过
$_COOKIE[]
获取 session id,并将其与$_SESSION[]
中存储的信息进行比较并进行 authentication。若 success,解禁 session storage 中存储的 session data。
session id 与普通 cookie 的另一个区别在于其有效期:我们可以通过
setcookie()
来指定 cookie 的有效期,在 cookie expire
之前它都将一致存储在 document.cookie
中。
而 session id 并不通过 setcookie()
来操纵。这是因为
session id 的 life span 很短:session 通常是临时的,一旦用户关闭对应的
tab 或 window,session 就将被销毁。
Reference
This article is a self-administered course note.
References in the article are from corresponding course materials if not specified.
Course info: Code, COMP3322. Lecturer, Dr. Tam Anthony Tat Chun.