# MySQL PHP 教程
> 原文: [http://zetcode.com/databases/mysqlphptutorial/](http://zetcode.com/databases/mysqlphptutorial/)
這是針對 MySQL 數據庫的 PHP 編程教程。 它涵蓋了使用 PHP 進行 MySQL 編程的基礎。 它使用通用 mysql 模塊。 這些示例是在 Ubuntu Linux 上創建和測試的。 在 ZetCode 上有類似的 [MySQL C API 教程](/db/mysqlc/), [MySQL MySQL 教程](/db/mysqlpython/), [MongoDB PHP 教程](/db/mongodbphp/)和 [PostgreSQL PHP 教程](/db/postgresqlphp/)。
如果您需要重新了解 PHP 語言,可以在 ZetCode 上找到完整的 [PHP 教程](/lang/php/)。
## 關于 MySQL 數據庫
MySQL 是領先的開源數據庫管理系統。 它是一個多用戶,多線程的數據庫管理系統。 MySQL 在網絡上特別流行。 它是非常流行的 _LAMP_ 平臺的組成部分之一。 Linux,Apache,MySQL 和 PHP。 目前,MySQL 由 Oracle 擁有。 MySQL 數據庫在最重要的 OS 平臺上可用。 它可以在 BSD Unix,Linux,Windows 或 Mac OS 上運行。 維基百科和 YouTube 使用 MySQL。 這些站點每天管理數百萬個查詢。 MySQL 有兩個版本:MySQL 服務器系統和 MySQL 嵌入式系統。
## 開始之前
我們需要安裝幾個包來執行本教程中的示例:`php5-cli`,`php5-mysql`,`mysql-server`和`mysql-client`。
`php5-cli`是 PHP5 編程語言的命令行解釋器。 本教程中的所有示例均在控制臺上創建。 我特意跳過了 Web 界面,以使示例更簡單,僅關注 PHP 和 MySQL。
如果您尚未安裝 MySQL,則必須安裝它。
```php
$ sudo apt-get install mysql-server
```
此命令將安裝 MySQL 服務器和其他各種包。 在安裝包時,提示我們輸入 MySQL 根帳戶的密碼。
接下來,我們將創建一個新的數據庫用戶和一個新的數據庫。 我們使用`mysql`客戶端。
```php
$ service mysql status
mysql start/running, process 1238
```
我們檢查 MySQL 服務器是否正在運行。 如果沒有,我們需要啟動服務器。 在 Ubuntu Linux 上,可以使用`service mysql start`命令來完成。
```php
$ sudo service mysql start
```
如果我們已經從包中安裝了 MySQL 數據庫,則上述命令是啟動 MySQL 的常用方法。
```php
$ sudo -b /usr/local/mysql/bin/mysqld_safe
```
上面的命令使用 MySQL 服務器啟動腳本啟動 MySQL 服務器。 我們啟動 MySQL 服務器的方式可能有所不同。 這取決于我們是否從源代碼或包安裝了 MySQL,也取決于 Linux 發行版。 有關更多信息,請查閱 [MySQL 的第一步](http://zetcode.com/databases/mysqltutorial/firststeps/)或您的 Linux 發行版信息。
接下來,我們將創建一個新的數據庫用戶和一個新的數據庫。 我們使用`mysql`客戶端。
```php
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 30
Server version: 5.0.67-0ubuntu6 (Ubuntu)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
+--------------------+
2 rows in set (0.00 sec)
```
我們使用 mysql 監視器客戶端應用連接到服務器。 我們使用根帳戶連接到數據庫。 我們用`SHOW DATABASES`語句顯示所有可用的數據庫。
```php
mysql> CREATE DATABASE mydb;
Query OK, 1 row affected (0.02 sec)
```
我們創建一個新的`mydb`數據庫。 在整個教程中,我們將使用此數據庫。
```php
mysql> CREATE USER user12@localhost IDENTIFIED BY '34klq*';
Query OK, 0 rows affected (0.00 sec)
mysql> USE mydb;
Database changed
mysql> GRANT ALL ON mydb.* to user12@localhost;
Query OK, 0 rows affected (0.00 sec)
mysql> quit;
Bye
```
我們創建一個新的數據庫用戶。 我們授予該用戶`mydb`數據庫所有表的所有特權。
## php5-mysql
為了從 PHP 語言連接到 MySQL 數據庫,我們必須安裝`php5-mysql`包。 這是 Debian / Ubuntu Linux 的包名稱。 在其他衍生產品上,名稱可能有所不同。 該包包含三個模塊。 它們也稱為擴展。
* `mysql`模塊
* `mysqli`模塊
* `pdo_mysql`
通用`mysql`模塊是 MySQL 數據庫的原始 PHP API。 我們的教程涵蓋了該模塊。 API 是程序性的。 該模塊不提供較新的 MySQL 數據庫的所有最新功能。 MySQL 改進的`mysqli`模塊是 MySQL 4.1.3 或更高版本的推薦模塊。 它提供了面向對象的 API 和過程 API。 與原始的`mysql`模塊相比,它具有一些優點和增強。
PHP 數據對象模塊`pdo_mysql`是 PHP 應用的數據庫抽象層。 如果我們編寫可移植的數據庫 PHP 腳本,則此模塊非常有用。
## 第一個腳本
以下腳本是一個簡單的 PHP 腳本。 如果此小腳本運行正常,則說明我們已安裝了所有必需的東西。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
echo mysql_get_server_info() . "\n";
mysql_close();
?>
```
我們連接到數據庫并獲取有關 MySQL 服務器的一些信息。
```php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
```
這是三個變量,分別包含主機名,用戶名和密碼。 連接到 MySQL 數據庫時需要這些變量。
```php
$r = mysql_connect($host, $user, $pass);
```
我們使用`mysql_connect()`函數連接到數據庫。 該函數返回一個布爾值,指示是否成功創建連接。 該函數具有 3 個參數。 第一個是安裝服務器的主機。 第二和第三個參數是用戶名和用戶密碼。
```php
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
```
現在我們檢查`$r`變量。 如果它包含布爾值`false`,則表示未創建與數據庫的連接。 我們調用`trigger_error()`函數來生成錯誤消息。 第一條通用消息發送給用戶。 記錄通過`trigger_error()`函數生成的更具體的錯誤消息。
```php
echo mysql_get_server_info() . "\n";
```
`mysql_get_server_info()`返回 MySQL 服務器版本。
```php
mysql_close();
```
`mysql_close()`函數關閉與數據庫的連接。 在本例中,不需要關閉連接,因為在腳本執行結束時,非持久性打開鏈接會自動關閉。 但是,這是一種好的編程習慣。
```php
$ php version.php
5.1.41-3ubuntu12.6
5.3.2-1ubuntu4.5
```
在我的系統上,我得到以下輸出。
我們有一個類似的腳本。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$query = "SELECT VERSION()";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
$row = mysql_fetch_row($rs);
echo "Version: $row[0]\n";
mysql_close();
?>
```
我們檢查 MySQL 數據庫的版本。 這次使用 SQL 查詢。
```php
$query = "SELECT VERSION()";
```
這是 SQL `SELECT`語句。 它返回數據庫的版本。 `VERSION()`是內置的 MySQL 函數。
```php
$rs = mysql_query($query);
```
`mysql_query()`函數在數據庫上執行 SQL 查詢。 這是一個`SELECT`查詢,因此結果是一個包含一些數據的結果集。
```php
if (!$rs) {
echo "Could not execute query: $query\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
```
如果發生錯誤,我們會生成一條錯誤消息。 否則,我們將打印執行的 SQL 查詢。
```php
$row = mysql_fetch_row($rs);
```
我們從結果集中獲取一行。 `$row`變量是一個包含數據的數組。
```php
echo "Version: $row[0]\n";
```
我們從數組中打印數據。 根據查詢的性質,我們知道數組只有一項,即 MySQL 版本字符串。
```php
$ php version2.php
Connection established
Query: SELECT VERSION() executed
Version: 5.1.62-0ubuntu0.11.10.1
```
腳本在我們系統上的輸出。
## 創建并填充表
接下來,我們將創建一個數據庫表并用數據填充它。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
function execute_query($query) {
$r = mysql_query($query);
if (!$r) {
echo "Cannot execute query: $query\n";
trigger_error(mysql_error());
} else {
echo "Query: $query executed\n";
}
}
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$query = "DROP TABLE IF EXISTS Cars";
execute_query($query);
$query = "CREATE TABLE Cars(Id INT PRIMARY KEY, Name TEXT,
Price INT) ENGINE=InnoDB";
execute_query($query);
$query = "INSERT INTO Cars VALUES(1,'Audi',52642)";
execute_query($query);
$query = "INSERT INTO Cars VALUES(2,'Mercedes',57127)";
execute_query($query);
$query = "INSERT INTO Cars VALUES(3,'Skoda',9000)";
execute_query($query);
$query = "INSERT INTO Cars VALUES(4,'Volvo',29000)";
execute_query($query);
$query = "INSERT INTO Cars VALUES(5,'Bentley',350000)";
execute_query($query);
$query = "INSERT INTO Cars VALUES(6,'Citroen',21000)";
execute_query($query);
$query = "INSERT INTO Cars VALUES(7,'Hummer',41400)";
execute_query($query);
$query = "INSERT INTO Cars VALUES(8,'Volkswagen',21600)";
execute_query($query);
mysql_close();
?>
```
在上面的代碼示例中,我們創建具有 8 行的`Cars`表。
```php
function execute_query($query) {
$r = mysql_query($query);
if (!$r) {
echo "Cannot execute query: $query\n";
trigger_error(mysql_error());
} else {
echo "Query: $query executed\n";
}
}
```
我們創建了一個自定義`execute_query()`函數,該函數將為每個`INSERT`語句調用。
```php
$r2 = mysql_select_db($db);
```
在使用數據庫表之前,我們必須選擇一個數據庫。 使用`mysql_select_db()`函數選擇一個數據庫。
```php
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
```
數據庫選擇過程的錯誤處理。
```php
$query = "DROP TABLE IF EXISTS Cars";
execute_query($query);
```
第一個查詢將刪除`Cars`表(如果已存在)。
```php
$query = "CREATE TABLE Cars(Id INT PRIMARY KEY, Name TEXT,
Price INT) ENGINE=InnoDB";
execute_query($query);
```
這是創建`Cars`表的 SQL 語句。
```php
$query = "INSERT INTO Cars VALUES(1,'Audi',52642)";
execute_query($query);
```
一輛汽車被插入表。
```php
if (!$ok) {
echo mysql_error();
die("Cannot execute query. \n");
}
```
如果發生錯誤,我們將打印錯誤消息并終止腳本。
```php
$ php create_fill.php
Connection established
Database selected
Query: DROP TABLE IF EXISTS Cars executed
Query: CREATE TABLE Cars(Id INT PRIMARY KEY, Name TEXT,
Price INT) ENGINE=InnoDB executed
Query: INSERT INTO Cars VALUES(1,'Audi',52642) executed
Query: INSERT INTO Cars VALUES(2,'Mercedes',57127) executed
Query: INSERT INTO Cars VALUES(3,'Skoda',9000) executed
Query: INSERT INTO Cars VALUES(4,'Volvo',29000) executed
Query: INSERT INTO Cars VALUES(5,'Bentley',350000) executed
Query: INSERT INTO Cars VALUES(6,'Citroen',21000) executed
Query: INSERT INTO Cars VALUES(7,'Hummer',41400) executed
Query: INSERT INTO Cars VALUES(8,'Volkswagen',21600) executed
```
執行`create_fill.php`腳本。
```php
mysql> SELECT * FROM Cars;
+----+------------+--------+
| Id | Name | Price |
+----+------------+--------+
| 1 | Audi | 52642 |
| 2 | Mercedes | 57127 |
| 3 | Skoda | 9000 |
| 4 | Volvo | 29000 |
| 5 | Bentley | 350000 |
| 6 | Citroen | 21000 |
| 7 | Hummer | 41400 |
| 8 | Volkswagen | 21600 |
+----+------------+--------+
8 rows in set (0.00 sec)
```
數據插入到`Cars`表中。
## 檢索數據
現在我們已經將一些數據插入數據庫中,我們想要取回它。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$query = "SELECT * FROM Cars LIMIT 5";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
while ($row = mysql_fetch_assoc($rs)) {
echo $row['Id'] . " " . $row['Name'] . " " . $row['Price'] . "\n";
}
mysql_close();
?>
```
在此示例中,我們從`Cars`表中檢索五行。
```php
$query = "SELECT * FROM Cars LIMIT 5";
```
該 SQL 語句從`Cars`表中選擇 5 行。
```php
$rs = mysql_query($query);
```
我們使用`mysql_query()`函數執行查詢并檢索結果集。
```php
if (!$rs) {
echo "Could not execute query: $query";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
```
如果查詢沒有成功,我們將生成一條錯誤消息。
```php
while ($row = mysql_fetch_assoc($rs)) {
echo $row['Id'] . " " . $row['Name'] . " " . $row['Price'] . "\n";
}
```
我們遍歷結果集并將數據打印到控制臺。 `mysql_fetch_assoc()`函數返回與提取的行相對應的字符串關聯數組,如果沒有更多行,則返回`FALSE`。 換句話說,函數調用從結果集中返回一行。 該行采用關聯數組的形式。 列名稱是關聯數組的鍵。 當結果集中沒有更多行時,該函數將返回`FALSE`,而`while`循環終止。
```php
$ php query.php
Connection established
Database selected
Query: SELECT * FROM Cars LIMIT 5 executed
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
```
這是示例的輸出。
在第二個示例中,我們將使用`mysql_fetch_row()`函數獲取數據。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$query = "SELECT Id, Name, Price From Cars LIMIT 5";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
$nrows = mysql_num_rows($rs);
for ($i = 0; $i < $nrows; $i++) {
$row = mysql_fetch_row($rs);
echo $row[0];
echo " ";
echo $row[1];
echo " ";
echo $row[1];
echo "\n";
}
mysql_close();
?>
```
我們從`Cars`表中獲得前 5 行。
```php
$nrows = mysql_num_rows($rs);
```
`mysql_num_rows()`函數從結果集中獲取行數。
```php
for ($i = 0; $i < $nrows; $i++) {
$row = mysql_fetch_row($rs);
echo $row[0];
echo " ";
echo $row[1];
echo " ";
echo $row[1];
echo "\n";
}
```
我們使用`for`循環遍歷返回的行。 `mysql_fetch_row()`函數從結果集中以枚舉數組的形式檢索行。
```php
$ php query.php
Connection established
Query: SELECT * FROM Cars LIMIT 5 executed
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
```
輸出。
在下面的示例中,我們顯示了如何從表中檢索特定行。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$name = "Volkswagen";
$query = sprintf("SELECT Id, Name, Price From Cars Where Name = '%s'",
mysql_real_escape_string($name));
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
while ($row = mysql_fetch_object($rs)) {
echo $row->Id;
echo " ";
echo $row->Name;
echo " ";
echo $row->Price;
echo "\n";
}
mysql_close();
?>
```
開發者在處理用戶輸入時必須考慮安全性問題。 我們必須始終處理來自外部世界的數據。 檢查數據的有效性。
```php
$name = "Volkswagen";
```
在腳本中,我們檢查`Caras`表中是否有`"Volkswagen"`。 此值可能來自 XML 文件或 Web 表單。 我們將展示如何檢查它。
```php
$query = sprintf("SELECT Id, Name, Price From Cars Where Name = '%s'",
mysql_real_escape_string($name));
```
我們使用`sprintf()`函數構建 SQL 語句。 我們使用`mysql_real_escape_string()`函數處理`$name`變量。 此函數轉義字符串中的特殊字符以用于 SQL 語句。 這樣可以防止 SQL 注入攻擊和數據損壞。 處理完變量后,將其放入 SQL 語句字符串中。
```php
while ($row = mysql_fetch_object($rs)) {
echo $row->Id;
echo " ";
echo $row->Name;
echo " ";
echo $row->Price;
echo "\n";
}
```
我們使用`mysql_fetch_object()`函數獲取數據。 該函數獲取結果行作為對象。 然后,我們使用對象表示法獲取表列。
```php
$ php query3.php
Connection established
Database selected
Query: SELECT Id, Name, Price From Cars Where Name = 'Volkswagen' executed
8 Volkswagen 21600
```
示例的輸出。 我們找到了汽車,并將整行打印到控制臺。
## 轉義字符
我們將有一個小示例演示如何轉義字符。 有些字符在數據庫環境中被認為是不安全的。 其中之一是單引號字符。
```php
mysql> CREATE TABLE IF NOT EXISTS Authors(Id INT PRIMARY KEY AUTO_INCREMENT,
-> Name VARCHAR(25)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.09 sec)
```
對于該示例,我們創建一個`Authors`表。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$name = "O'Neill";
$name_es = mysql_real_escape_string($name);
$query = "INSERT INTO Authors(Name) VALUES('$name_es')";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
mysql_close();
?>
```
我們在`Authors`表中插入一個新作者。 作者的名字叫奧尼爾。 該名稱具有不安全的單引號字符。
```php
$name_es = mysql_real_escape_string($name);
```
這就是為什么我們使用`mysql_real_escape_string()`函數來轉義此字符。
```php
$query = "INSERT INTO Authors(Name) VALUES('$name_es')";
$rs = mysql_query($query);
```
我們創建該語句并執行它。
```php
mysql> SELECT * FROM Authors;
+----+---------+
| Id | Name |
+----+---------+
| 1 | O'Neill |
+----+---------+
1 row in set (0.00 sec)
```
該名稱已成功寫入表中。
## 列標題
接下來,我們將展示如何使用數據庫表中的數據打印列標題。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$query = "SELECT * From Cars LIMIT 8";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
$cname1 = mysql_fetch_field($rs, 0);
$cname2 = mysql_fetch_field($rs, 1);
$cname3 = mysql_fetch_field($rs, 2);
printf("%3s %-11s %8s\n", $cname1->name, $cname2->name,
$cname3->name);
while ($row = mysql_fetch_row($rs)) {
printf("%3s %-11s %8s\n", $row[0], $row[1], $row[2]);
}
mysql_close();
?>
```
同樣,我們將`Writers`表的內容打印到控制臺。 現在,我們也包括列的名稱。
```php
$cname1 = mysql_fetch_field($rs, 0);
$cname2 = mysql_fetch_field($rs, 1);
$cname3 = mysql_fetch_field($rs, 2);
```
要獲取特定的字段名稱,我們利用`mysql_fetch_field()`函數。 該函數返回一個包含列信息的對象。
```php
printf("%3s %-11s %8s\n", $cname1->name, $cname2->name,
$cname3->name);
```
列名稱已打印并格式化。 `name`屬性包含列名。
```php
$ php columns.php
Connection established
Database selected
Query: SELECT * From Cars LIMIT 8 executed
Id Name Price
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
6 Citroen 21000
7 Hummer 41400
8 Volkswagen 21600
```
腳本的輸出。
## 行和列數
以下腳本計算查詢返回的字段/列和行數。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$query = "SELECT * FROM Cars WHERE Id IN (1, 2, 3)";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
echo "We have " . mysql_num_fields($rs) . " fields\n";
echo "We have " . mysql_num_rows($rs) . " rows\n";
print_r(mysql_fetch_row($rs));
mysql_close();
?>
```
我們從`Cars`表中選擇三行。 我們計算查詢返回的行數和列數。
```php
$query = "SELECT * FROM Cars WHERE Id IN (1, 2, 3)";
```
這是要執行的查詢。 它從`Cars`表中選擇前三行。
```php
echo "We have " . mysql_num_fields($rs) . " fields\n";
```
`mysql_num_fields()`返回查詢返回的字段數。
```php
echo "We have " . mysql_num_rows($rs) . " rows\n";
```
`mysql_num_rows()`返回查詢返回的行數。
```php
print_r(mysql_fetch_row($rs));
```
我們打印數組的內容。
```php
$ php fields_rows.php
Connection established
Database selected
Query: SELECT * FROM Cars WHERE Id IN (1, 2, 3) executed
We have 3 fields
We have 3 rows
Array
(
[0] => 1
[1] => Audi
[2] => 52642
)
```
運行腳本。
## 寫入圖像
有些人喜歡將其圖像放入數據庫中,有些人則希望將其保留在文件系統中以供其應用使用。 當我們處理大量圖像時,會出現技術難題。 圖像是二進制數據。 MySQL 數據庫具有一種特殊的數據類型來存儲稱為`BLOB`(二進制大對象)的二進制數據。
```php
mysql> CREATE TABLE Images(Id INT PRIMARY KEY AUTO_INCREMENT, Data MEDIUMBLOB);
Query OK, 0 rows affected (0.06 sec)
```
對于此示例,我們創建一個名為`Images`的新表。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$file = "woman.jpg";
$img = fopen($file, 'r');
if (!$img) {
echo "Cannot open file for writing\n";
trigger_error("Cannot open file for writing\n", E_USER_ERROR);
}
$data = fread($img, filesize($file));
if (!$data) {
echo "Cannot read image data\n";
trigger_error("Cannot read image data\n", E_USER_ERROR);
}
$es_data = mysql_real_escape_string($data);
fclose($img);
$query = "INSERT INTO Images(Id, Data) Values(1, '$es_data')";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query successfully executed\n";
}
mysql_close();
?>
```
在上面的腳本中,我們讀取 JPG 圖像并將其插入到`Images`表中。
```php
$file = "woman.jpg";
```
這是我們從文件系統讀取并寫入數據庫的映像名稱。 它與腳本名稱位于同一目錄中。
```php
$img = fopen($file, 'r');
if (!$img) {
echo "Cannot open file for writing\n";
trigger_error("Cannot open file for writing\n", E_USER_ERROR);
}
$data = fread($img, filesize($file));
if (!$data) {
echo "Cannot read image data\n";
trigger_error("Cannot read image data\n", E_USER_ERROR);
}
```
我們打開并閱讀圖像。 `fread()`函數以字符串形式返回數據。
```php
$es_data = mysql_real_escape_string($data);
```
我們逃避不安全的字符。
```php
fclose($img);
```
我們關閉圖像文件的句柄。
```php
$query = "INSERT INTO Images(Id, Data) Values(1, '$es_data')";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query successfully executed\n";
}
```
我們將數據插入到新創建的`Images`表中。
## 讀取圖像
在前面的示例中,我們已將圖像插入數據庫表中。 現在,我們將從表中讀取圖像。
```php
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "mydb";
$r = mysql_connect($host, $user, $pass);
if (!$r) {
echo "Could not connect to server\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Connection established\n";
}
$r2 = mysql_select_db($db);
if (!$r2) {
echo "Cannot select database\n";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Database selected\n";
}
$query = "SELECT Data FROM Images WHERE Id=1";
$rs = mysql_query($query);
if (!$rs) {
echo "Could not execute query: $query";
trigger_error(mysql_error(), E_USER_ERROR);
} else {
echo "Query: $query executed\n";
}
$row = mysql_fetch_row($rs);
$file = "woman2.jpg";
$img = fopen($file, 'wb');
if (!$img) {
echo "Cannot open file for writing\n";
trigger_error("Cannot open file for writing\n", E_USER_ERROR);
}
$r3 = fwrite($img, $row[0]);
if (!$r3) {
echo "Cannot write image to file\n";
trigger_error("Cannot write image to file\n", E_USER_ERROR);
}
fclose($img);
mysql_close();
?>
```
我們從`Images`表中讀取了一張圖像。
```php
$query = "SELECT Data FROM Images WHERE Id=1";
```
我們從表中選擇一條記錄。
```php
$row = mysql_fetch_row($rs);
```
我們從結果集中獲取一行。 只有一行包含圖像數據。
```php
$file = "woman2.jpg";
```
我們將創建一個名為`woman2.jpg`的新圖像文件。
```php
$img = fopen($file, 'wb');
if (!$img) {
echo "Cannot open file for writing\n";
trigger_error("Cannot open file for writing\n", E_USER_ERROR);
}
```
我們打開一個可寫的二進制文件。
```php
$r3 = fwrite($img, $row[0]);
if (!$r3) {
echo "Cannot write image to file\n";
trigger_error("Cannot write image to file\n", E_USER_ERROR);
}
```
我們使用`fwrite()`函數將數據寫入文件系統。
現在我們在當前目錄中應該有一個名為`woman2.jpg`的映像。 我們可以檢查它是否與我們插入表中的圖像相同。
## 事務支持
事務是針對一個或多個數據庫中數據的數據庫操作的基本單位。 事務中所有 SQL 語句的影響可以全部提交給數據庫,也可以全部回滾。
MySQL 數據庫具有不同類型的存儲引擎。 最常見的是 MyISAM 和 InnoDB 引擎。 MyISAM 是默認的。 在數據安全性和數據庫速度之間需要權衡。 MyISAM 表的處理速度更快,并且不支持事務。 另一方面,InnoDB 表可以更安全地防止數據丟失。 他們支持事務。 它們處理較慢。
```php
<?php
mysql_connect('localhost', 'testuser', 'test623')
or die("cannot connect to database\n");
mysql_select_db("testdb") or die(mysql_error());
$r1 = mysql_query("UPDATE Writers SET Name = 'Leo Tolstoy' WHERE Id = 1")
or die(mysql_error());
$r2 = mysql_query("UPDATE Writers SET Name = 'Boris Pasternak' WHERE Id = 2")
or die(mysql_error());
$r3 = mysql_query("UPDATE Writer SET Name = 'Leonid Leonov' WHERE Id = 3")
or die(mysql_error());
mysql_close();
?>
```
在此腳本中,我們嘗試更新三行。 該表的存儲引擎是 MyISAM。
```php
$r1 = mysql_query("UPDATE Writers SET Name = 'Leo Tolstoy' WHERE Id = 1")
or die(mysql_error());
$r2 = mysql_query("UPDATE Writers SET Name = 'Boris Pasternak' WHERE Id = 2")
or die(mysql_error());
```
在這里,我們要更改第 1 行和第 2 行的作者姓名。
```php
$r3 = mysql_query("UPDATE Writer SET Name = 'Leonid Leonov' WHERE Id = 3")
or die(mysql_error());
```
SQL 語句中有錯誤。 沒有`Writer`表。
```php
$ php update.php
Table 'testdb.Writer' doesn't exist
mysql> SELECT * FROM Writers;
+----+-------------------+
| Id | Name |
+----+-------------------+
| 1 | Leo Tolstoy |
| 2 | Boris Pasternak |
| 3 | Lion Feuchtwanger |
| 4 | Emile Zola |
| 5 | Truman Capote |
| 6 | O'Neill |
+----+-------------------+
6 rows in set (0.00 sec)
```
運行腳本會出現錯誤。 但是,正如我們所看到的,前兩行已經更改。
在本教程的最后一個示例中,我們將重新創建`Writers`表。 這次,該表將為 InnoDB 類型。 InnoDB MySQL 數據庫表支持事務。
```php
DROP TABLE Writers;
CREATE TABLE IF NOT EXISTS Writers(Id INT PRIMARY KEY AUTO_INCREMENT,
Name VARCHAR(25)) ENGINE=INNODB;
INSERT INTO Writers(Name) VALUES('Jack London');
INSERT INTO Writers(Name) VALUES('Honore de Balzac');
INSERT INTO Writers(Name) VALUES('Lion Feuchtwanger');
INSERT INTO Writers(Name) VALUES('Emile Zola');
INSERT INTO Writers(Name) VALUES('Truman Capote');
```
這是`writers.sql`文件。 它用于重新創建`Writers`表。
```php
mysql> source writers.sql
Query OK, 0 rows affected (0.03 sec)
Query OK, 0 rows affected (0.10 sec)
Query OK, 1 row affected (0.02 sec)
Query OK, 1 row affected (0.03 sec)
Query OK, 1 row affected (0.02 sec)
Query OK, 1 row affected (0.02 sec)
Query OK, 1 row affected (0.02 sec)
```
我們可以使用`source`命令來加載和執行 SQL 腳本。
```php
<?php
mysql_connect('localhost', 'testuser', 'test623')
or die("cannot connect to database\n");
mysql_select_db("testdb") or die(mysql_error());
mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");
$r1 = mysql_query("DELETE FROM Writers WHERE Id = 3")
or die(mysql_error());
$r2 = mysql_query("DELETE FROM Writers WHERE Id = 4")
or die(mysql_error());
$r3 = mysql_query("DELETE FROM Writer WHERE Id = 5")
or die(mysql_error());
if ($r1 and $r2 and $r3) {
mysql_query("COMMIT");
} else {
mysql_query("ROLLBACK");
}
mysql_close();
?>
```
現在,我們將執行上面的腳本。 我們要從表中刪除三行。 第三個 SQL 語句有一個錯誤。
```php
mysql_query("START TRANSACTION");
```
`START TRANSACTION`語句開始一個新的事務。 必須使用`COMMIT`語句將所有更改永久化,或使用`ROLLBACK`語句將其忽略。
```php
if ($r1 and $r2 and $r3) {
mysql_query("COMMIT");
} else {
mysql_query("ROLLBACK");
}
```
僅當所有三個 SQL 語句都返回`True`時,才提交語句。 否則,我們將它們回滾。 在我們的情況下,`$r3`變量為`False`,因此不會使語句成為永久語句,也不會從表中刪除行。
```php
$ php transaction.php
Table 'testdb.Writer' doesn't exist
mysql> SELECT * FROM Writers;
+----+-------------------+
| Id | Name |
+----+-------------------+
| 1 | Jack London |
| 2 | Honore de Balzac |
| 3 | Lion Feuchtwanger |
| 4 | Emile Zola |
| 5 | Truman Capote |
+----+-------------------+
5 rows in set (0.00 sec)
```
在將更改提交到數據庫之前,發生了錯誤。 調用`ROLLBACK`語句,并且沒有發生刪除。
[Tweet](https://twitter.com/share)
這是 MySQL PHP 教程。 您可能也對 [MySQL C API 教程](/db/mysqlc/), [MySQL Python 教程](/db/mysqlpython/)或 [MySQL Visual Basic 教程](/db/mysqlvb/)感興趣。
- ZetCode 數據庫教程
- MySQL 教程
- MySQL 簡介
- MySQL 安裝
- MySQL 的第一步
- MySQL 快速教程
- MySQL 存儲引擎
- MySQL 數據類型
- 在 MySQL 中創建,更改和刪除表
- MySQL 表達式
- 在 MySQL 中插入,更新和刪除數據
- MySQL 中的SELECT語句
- MySQL 子查詢
- MySQL 約束
- 在 MySQL 中導出和導入數據
- 在 MySQL 中連接表
- MySQL 函數
- MySQL 中的視圖
- MySQL 中的事務
- MySQL 存儲過程
- MySQL Python 教程
- MySQL Perl 教程
- MySQL & Perl DBI
- 使用 Perl 連接到 MySQL 數據庫
- MySQL 中的 Perl 錯誤處理
- 使用 Perl 進行 MySQL 查詢
- 在 MySQL 中使用 Perl 綁定參數&列
- 在 MySQL 中使用 Perl 處理圖像
- 使用 Perl 獲取 MySQL 元數據
- Perl 的 MySQL 事務
- MySQL C API 編程教程
- MySQL Visual Basic 教程
- MySQL PHP 教程
- MySQL Java 教程
- MySQL Ruby 教程
- MySQL C# 教程
- SQLite 教程
- SQLite 簡介
- sqlite3 命令行工具
- 在 SQLite 中創建,刪除和更改表
- SQLite 表達式
- SQLite 插入,更新,刪除數據
- SQLite SELECT語句
- SQLite 約束
- SQLite 連接表
- SQLite 函數
- SQLite 視圖,觸發器,事務
- SQLite C 教程
- SQLite Python 教程
- SQLite Perl 教程
- Perl DBI
- 使用 Perl 連接到 SQLite 數據庫
- SQLite Perl 錯誤處理
- 使用 Perl 的 SQLite 查詢
- 使用 Perl 綁定 SQLite 參數&列
- 使用 Perl 在 SQLite 中處理圖像
- 使用 Perl 獲取 SQLite 元數據
- 使用 Perl 進行 SQLite 事務
- SQLite Ruby 教程
- 連接到 SQLite 數據庫
- 在 SQLite 中使用 Ruby 進行 SQL 查詢
- 綁定參數
- 處理圖像
- 使用 Ruby 獲取 SQLite 元數據
- Ruby 的 SQLite 事務
- SQLite C# 教程
- SQLite C# 簡介
- 使用SqliteDataReader檢索數據
- ADO.NET 數據集
- 使用 C# 在 SQLite 中處理圖像
- 使用 C# 獲取 SQLite 元數據
- 使用 C# 的 SQLite 事務
- SQLite Visual Basic 教程
- SQLite Visual Basic 簡介
- 使用SqliteDataReader檢索數據
- ADO.NET 的數據集
- 使用 Visual Basic 在 SQLite 中處理圖像
- 使用 Visual Basic 獲取 SQLite 元數據
- 使用 Visual Basic 的 SQLite 事務
- PostgreSQL C 教程
- PostgreSQL Ruby 教程
- PostgreSQL PHP 教程
- PostgreSQL PHP 編程簡介
- 在 PostgreSQL 中使用 PHP 檢索數據
- 在 PostgreSQL 中使用 PHP 處理圖像
- 用 PHP 獲取 PostgreSQL 元數據
- 在 PostgreSQL 中使用 PHP 進行事務
- PostgreSQL Java 教程
- Apache Derby 教程
- Derby 簡介
- Derby 的安裝&配置
- Derby 工具
- ij 工具
- Derby 中的 SQL 查詢
- 在 Derby 中使用 JDBC 進行編程
- Derby 安全
- 使用 Derby & Apache Tomcat
- NetBeans 和 Derby
- SQLAlchemy 教程
- SQLAlchemy 簡介
- 原始 SQL
- 模式定義語言
- SQL 表達式語言
- SQLAlchemy 中的對象關系映射器
- MongoDB PHP 教程
- MongoDB JavaScript 教程
- MongoDB Ruby 教程
- Spring JdbcTemplate 教程
- JDBI 教程
- MyBatis 教程
- Hibernate Derby 教程
- ZetCode .NET 教程
- Visual Basic 教程
- Visual Basic
- Visual Basic 語法結構
- 基本概念
- Visual Basic 數據類型
- Visual Basic 中的字符串
- 運算符
- 控制流
- Visual Basic 數組
- Visual Basic 中的過程&函數
- 在 Visual Basic 中組織代碼
- 面向對象編程
- Visual Basic 中的面向對象編程 II
- Visual Basic 中的集合
- 輸入和輸出
- C# 教程
- C# 語言
- C# 語法結構
- C# 基礎
- C# 數據類型
- C# 中的字符串
- C# 運算符
- C# 中的流控制
- C# 數組
- C# 面向對象編程
- C# 中的方法
- C# 面向對象編程 II
- C# 屬性
- C# 結構
- C# 委托
- 命名空間
- C# 集合
- C# 輸入和輸出
- C# 目錄教程
- C# 字典教程
- 在 C# 中讀取文本文件
- C# 中的日期和時間
- 在 C# 中讀取網頁
- C# HttpClient教程
- ASP.NET Core 教程
- ZetCode 圖形教程
- Java 2D 游戲教程
- Java 游戲基礎
- 動畫
- 移動精靈
- 碰撞檢測
- Java 益智游戲
- Java Snake
- Breakout 游戲
- Java 俄羅斯方塊
- Java 吃豆人
- Java 太空侵略者
- Java 掃雷
- Java 推箱子
- Java 2D 教程
- 介紹
- 基本繪圖
- 形狀和填充
- 透明度
- 合成
- 剪裁
- 變換
- 特效
- 圖像
- 文字和字體
- 命中測試,移動物體
- 俄羅斯方塊
- Cario 圖形教程
- Cario 圖形庫
- Cario 定義
- Cairo 后端
- Cairo 基本圖形
- 形狀和填充
- 漸變
- 透明度
- 合成
- 剪裁和遮罩
- 變換
- Cairo 文字
- Cairo 中的圖像
- 根窗口
- PyCairo 教程
- PyCairo 簡介
- PyCairo 后端
- PyCairo 中的基本繪圖
- PyCairo 形狀和填充
- PyCairo 漸變
- PyCairo 剪裁&遮罩
- PyCairo 的透明度
- PyCairo 中的變換
- PyCairo 中的文字
- PyCairo 中的圖像
- 根窗口
- HTML5 畫布教程
- 介紹
- HTML5 畫布中的直線
- HTML5 畫布形狀
- HTML5 畫布填充
- HTML5 畫布中的透明度
- HTML5 畫布合成
- HTML5 canvas 中的變換
- HTML5 畫布中的文字
- HTML5 畫布中的動畫
- HTML5 畫布中的 Snake
- ZetCode GUI 教程
- Windows API 教程
- Windows API 簡介
- Windows API main函數
- Windows API 中的系統函數
- Windows API 中的字符串
- Windows API 中的日期和時間
- Windows API 中的一個窗口
- UI 的第一步
- Windows API 菜單
- Windows API 對話框
- Windows API 控件 I
- Windows API 控件 II
- Windows API 控件 III
- Windows API 中的高級控件
- Windows API 中的自定義控件
- Windows API 中的 GDI
- PyQt4 教程
- PyQt4 簡介
- PyQt4 中的第一個程序
- PyQt4 中的菜單和工具欄
- PyQt4 中的布局管理
- PyQt4 中的事件和信號
- PyQt4 中的對話框
- PyQt4 小部件
- PyQt4 小部件 II
- PyQt4 中的拖放
- PyQt4 中的繪圖
- PyQt4 中的自定義小部件
- PyQt4 中的俄羅斯方塊游戲
- PyQt5 教程
- PyQt5 簡介
- PyQt5 日期和時間
- PyQt5 中的第一個程序
- PyQt5 中的菜單和工具欄
- PyQt5 中的布局管理
- PyQt5 中的事件和信號
- PyQt5 中的對話框
- PyQt5 小部件
- PyQt5 小部件 II
- PyQt5 拖放
- PyQt5 中的繪圖
- PyQt5 中的自定義小部件
- PyQt5 中的俄羅斯方塊
- Qt4 教程
- Qt4 工具包簡介
- Qt4 工具類
- Qt4 中的字符串
- Qt4 中的日期和時間
- 在 Qt4 中使用文件和目錄
- Qt4 中的第一個程序
- Qt4 中的菜單和工具欄
- Qt4 中的布局管理
- Qt4 中的事件和信號
- Qt4 小部件
- Qt4 小部件 II
- Qt4 中的繪圖
- Qt4 中的自定義小部件
- Qt4 中的打磚塊游戲
- Qt5 教程
- Qt5 工具包簡介
- Qt5 中的字符串
- Qt5 中的日期和時間
- Qt5 中的容器
- 在 Qt5 中處理文件和目錄
- Qt5 中的第一個程序
- Qt5 中的菜單和工具欄
- Qt5 中的布局管理
- Qt5 中的事件和信號
- Qt5 小部件
- Qt5 小部件 II
- Qt5 中的繪圖
- Qt5 中的自定義小部件
- Qt5 中的貪食蛇
- Qt5 中的打磚塊游戲
- PySide 教程
- PySide 工具包簡介
- PySide 中的第一個程序
- PySide 中的菜單和工具欄
- PySide 中的布局管理
- PySide 中的事件和信號
- PySide 中的對話框
- PySide 小部件
- PySide 小部件 II
- 在 PySide 中拖放
- 在 PySide 中繪圖
- PySide 中的自定義小部件
- PySide 中的俄羅斯方塊游戲
- Tkinter 教程
- Tkinter 簡介
- Tkinter 中的布局管理
- Tkinter 標準小部件屬性
- Tkinter 小部件
- Tkinter 中的菜單和工具欄
- Tkinter 中的對話框
- Tkinter 中的繪圖
- Tkinter 中的貪食蛇
- Tcl/Tk 教程
- Tcl/Tk 簡介
- Tcl/Tk 中的布局管理
- Tcl/Tk 小部件
- Tcl/Tk 中的菜單和工具欄
- Tcl/Tk 中的對話框
- Tcl/Tk 繪圖
- 貪食蛇
- Qt 快速教程
- Java Swing 教程
- Java Swing 簡介
- Java Swing 首個程序
- Java Swing 中的菜單和工具欄
- Swing 布局管理
- GroupLayout管理器
- Java Swing 事件
- 基本的 Swing 組件
- 基本的 Swing 組件 II
- Java Swing 對話框
- Java Swing 模型架構
- Swing 中的拖放
- Swing 中的繪圖
- Java Swing 中的可調整大小的組件
- Java Swing 中的益智游戲
- 俄羅斯方塊
- JavaFX 教程
- JavaFX 簡介
- JavaFX 首個程序
- JavaFX 布局窗格
- 基本的 JavaFX 控件
- 基本 JavaFX 控件 II
- JavaFX 事件
- JavaFX 效果
- JavaFX 動畫
- JavaFX 畫布
- JavaFX 圖表
- Java SWT 教程
- Java SWT 簡介
- Java SWT 中的布局管理
- Java SWT 中的菜單和工具欄
- Java SWT 中的小部件
- Table小部件
- Java SWT 中的對話框
- Java SWT 繪圖
- Java SWT 中的貪食蛇
- wxWidgets 教程
- wxWidgets 簡介
- wxWidgets 助手類
- wxWidgets 中的第一個程序
- wxWidgets 中的菜單和工具欄
- wxWidgets 中的布局管理
- wxWidgets 中的事件
- wxWidgets 中的對話框
- wxWidgets 小部件
- wxWidgets 小部件 II
- wxWidgets 中的拖放
- wxWidgets 中的設備上下文
- wxWidgets 中的自定義小部件
- wxWidgets 中的俄羅斯方塊游戲
- wxPython 教程
- wxPython 簡介
- 第一步
- 菜單和工具欄
- wxPython 中的布局管理
- wxPython 中的事件
- wxPython 對話框
- 小部件
- wxPython 中的高級小部件
- wxPython 中的拖放
- wxPython 圖形
- 創建自定義小部件
- wxPython 中的應用框架
- wxPython 中的俄羅斯方塊游戲
- C# Winforms Mono 教程
- Mono Winforms 簡介
- Mono Winforms 中的第一步
- Mono Winforms 中的布局管理
- Mono Winforms 中的菜單和工具欄
- Mono Winforms 中的基本控件
- Mono Winforms 中的高級控件
- 對話框
- Mono Winforms 中的拖放
- Mono Winforms 中的繪圖
- Mono Winforms 中的貪食蛇
- Java Gnome 教程
- Java Gnome 簡介
- Java Gnome 的第一步
- Java Gnome 中的布局管理
- Java Gnome 中的布局管理 II
- Java Gnome 中的菜單
- Java Gnome 中的工具欄
- Java Gnome 中的事件
- Java Gnome 中的小部件
- Java Gnome 中的小部件 II
- Java Gnome 中的高級小部件
- Java Gnome 中的對話框
- Java Gnome 中的 Pango
- 在 Java Gnome 中用 Cairo 繪圖
- Cario 繪圖 II
- Java Gnome 中的貪食蛇
- QtJambi 教程
- QtJambi 簡介
- QtJambi 中的布局管理
- QtJambi 中的小部件
- QtJambi 中的菜單和工具欄
- QtJambi 對話框
- QtJambi 中的繪圖
- QtJambi 中的自定義小部件
- 貪食蛇
- GTK+ 教程
- GTK+ 簡介
- GTK+ 中的第一個程序
- GTK+ 中的菜單和工具欄
- GTK+ 布局管理
- GTK+ 事件和信號
- GTK+ 對話框
- GTK+ 小部件
- GTK+ 小部件 II
- GtkTreeView小部件
- GtkTextView小部件
- 自定義 GTK+ 小部件
- Ruby GTK 教程
- Ruby GTK 簡介
- Ruby GTK 中的布局管理
- Ruby GTK 中的小部件
- Ruby GTK 中的菜單和工具欄
- Ruby GTK 中的對話框
- Ruby GTK Cario 繪圖
- Ruby GTK 中的自定義小部件
- Ruby GTK 中的貪食蛇
- GTK# 教程
- GTK# 簡介
- GTK 的第一步
- GTK# 中的布局管理
- GTK 中的菜單
- GTK# 中的工具欄
- GTK# 中的事件
- GTK# 中的小部件
- GTK 中的小部件 II
- GTK# 中的高級小部件
- GTK# 中的對話框
- Pango
- GTK# 中的 Cario 繪圖
- GTK# 中的 Cario 繪圖 II
- GTK# 中的自定義小部件
- Visual Basic GTK# 教程
- Visual Basic GTK# 簡介
- 布局管理
- 小部件
- 菜單和工具欄
- 對話框
- Cario 繪圖
- 自定義小部件
- 貪食蛇
- PyGTK 教程
- PyGTK 簡介
- PyGTK 的第一步
- PyGTK 中的布局管理
- PyGTK 中的菜單
- PyGTK 中的工具欄
- PyGTK 中的事件和信號
- PyGTK 中的小部件
- PyGTK 中的小部件 II
- PyGTK 中的高級小部件
- PyGTK 中的對話框
- Pango
- Pango II
- PyGTK 中的 Cario 繪圖
- Cario 繪圖 II
- PyGTK 中的貪食蛇游戲
- PyGTK 中的自定義小部件
- PHP GTK 教程
- PHP GTK 簡介
- PHP GTK 中的布局管理
- PHP GTK 中的小部件
- PHP GTK 中的菜單和工具欄
- 對話框
- Cario 繪圖
- 自定義小部件
- 貪食蛇
- C# Qyoto 教程
- Qyoto 介紹
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜單和工具欄
- Qyoto 對話框
- Qyoto 中的繪圖
- Qyoto 中的繪圖 II
- Qyoto 中的自定義小部件
- 貪食蛇
- Ruby Qt 教程
- Ruby Qt 簡介
- Ruby Qt 中的布局管理
- Ruby Qt 中的小部件
- 菜單和工具欄
- Ruby Qt 中的對話框
- 用 Ruby Qt 繪圖
- Ruby Qt 中的自定義小部件
- Ruby Qt 中的貪食蛇
- Visual Basic Qyoto 教程
- Qyoto 介紹
- 布局管理
- Qyoto 中的小部件
- Qyoto 中的菜單和工具欄
- Qyoto 對話框
- Qyoto 中的繪圖
- Qyoto 中的自定義小部件
- 貪食蛇
- Mono IronPython Winforms 教程
- 介紹
- IronPython Mono Winforms 中的第一步
- 布局管理
- 菜單和工具欄
- Mono Winforms 中的基本控件
- Mono Winforms 中的基本控件 II
- Mono Winforms 中的高級控件
- 對話框
- Mono Winforms 中的拖放
- 繪圖
- IronPython Mono Winforms 中的繪圖 II
- IronPython Mono Winforms 中的貪食蛇
- IronPython Mono Winforms 中的俄羅斯方塊游戲
- FreeBASIC GTK 教程
- Jython Swing 教程
- Jython Swing 簡介
- Jython Swing 中的布局管理
- Jython Swing 中的組件
- Jython Swing 中的菜單和工具欄
- Jython Swing 中的對話框
- Jython Swing 中的繪圖
- Jython Swing 中的半字節
- JRuby Swing 教程
- JRuby Swing 簡介
- JRuby Swing 中的布局管理
- JRuby Swing 中的組件
- 菜單和工具欄
- JRuby Swing 中的對話框
- 在 JRuby Swing 中繪圖
- JRuby Swing 中的貪食蛇
- Visual Basic Winforms 教程
- Visual Basic Winforms 簡介
- 布局管理
- 基本控制
- 進階控件
- 菜單和工具欄
- 對話框
- 繪圖
- 拖放
- 貪食蛇
- JavaScript GTK 教程
- JavaScript GTK 簡介
- 布局管理
- JavaScript GTK 中的小部件
- JavaScript GTK 中的菜單和工具欄
- JavaScript GTK 中的對話框
- JavaScript GTK 中的 Cario 繪圖
- ZetCode Java 教程
- Java 教程
- Java 語言
- Java 語法結構
- Java 基礎
- Java 數據類型
- Java 數據類型 II
- Java 字符串
- Java 數組
- Java 表達式
- Java 控制流程
- Java 面向對象的編程
- Java 方法
- Java 面向對象編程 II
- Java 包
- Java 中的異常
- Java 集合
- Java 流
- Java Future 教程
- Java Comparable和Comparator
- Java DOM 教程
- Java MVC 教程
- Java SAX 教程
- Java JAXB 教程
- Java JSON 處理教程
- Java H2 教程
- MongoDB Java 教程
- Java 正則表達式教程
- Java PDFBox 教程
- Java 文件教程
- Java Files.list教程
- Java Files.walk教程
- Java DirectoryStream教程
- Java 外部與內部迭代器
- Java 文件大小
- 用 Java 創建目錄
- 用 Java 創建文件
- Java Log4j 教程
- Gson 教程
- Java RequestDispatcher
- Java HTTP GET/POST 請求
- Java InputStream教程
- Java FileOutputStream教程
- Java FileInputStream教程
- Java ZipInputStream教程
- Java FileWriter教程
- EJB 簡介
- Java forEach教程
- Jetty 教程
- Tomcat Derby 教程
- Stripes 介紹
- 使用 Stripes 的 Java webapp,MyBatis,& Derby
- EclipseLink 簡介
- Java 中的數據源
- JSTL 中的 SQL 查詢標記
- Java 驗證過濾器
- Hibernate 驗證器
- 用 Java 顯示圖像
- Play 框架簡介
- Spark Java 簡介
- Java ResourceBundle教程
- Jtwig 教程
- Java Servlet 教程
- Java 套接字教程
- FreeMarker 教程
- Android 教程
- Java EE 5 教程
- JSoup 教程
- JFreeChart 教程
- ImageIcon教程
- 用 Java 復制文件
- Java 文件時間教程
- 如何使用 Java 獲取當前日期時間
- Java 列出目錄內容
- Java 附加到文件
- Java ArrayList教程
- 用 Java 讀寫 ICO 圖像
- Java int到String的轉換
- Java HashSet教程
- Java HashMap教程
- Java static關鍵字
- Java 中的HashMap迭代
- 用 Java 過濾列表
- 在 Java 中讀取網頁
- Java 控制臺應用
- Java 集合的便利工廠方法
- Google Guava 簡介
- OpenCSV 教程
- 用 Java8 的StringJoiner連接字符串
- Java 中元素迭代的歷史
- Java 謂詞
- Java StringBuilder
- Java 分割字串教學
- Java NumberFormat
- Java TemporalAdjusters教程
- Apache FileUtils教程
- Java Stream 過濾器
- Java 流歸約
- Java 流映射
- Java InputStreamReader教程
- 在 Java 中讀取文本文件
- Java Unix 時間
- Java LocalTime
- Java 斐波那契
- Java ProcessBuilder教程
- Java 11 的新功能
- ZetCode JavaScript 教程
- Ramda 教程
- Lodash 教程
- Collect.js 教程
- Node.js 簡介
- Node HTTP 教程
- Node-config 教程
- Dotenv 教程
- Joi 教程
- Liquid.js 教程
- faker.js 教程
- Handsontable 教程
- PouchDB 教程
- Cheerio 教程
- Axios 教程
- Jest 教程
- JavaScript 正則表達式
- 用 JavaScript 創建對象
- Big.js 教程
- Moment.js 教程
- Day.js 教程
- JavaScript Mustache 教程
- Knex.js 教程
- MongoDB JavaScript 教程
- Sequelize 教程
- Bookshelf.js 教程
- Node Postgres 教程
- Node Sass 教程
- Document.querySelector教程
- Document.all教程
- JSON 服務器教程
- JavaScript 貪食蛇教程
- JavaScript 構建器模式教程
- JavaScript 數組
- XMLHttpRequest教程
- 從 JavaScript 中的 URL 讀取 JSON
- 在 JavaScript 中循環遍歷 JSON 數組
- jQuery 教程
- Google 圖表教程
- ZetCode Kotlin 教程
- Kotlin Hello World 教程
- Kotlin 變量
- Kotlin 的運算符
- Kotlin when表達式
- Kotlin 數組
- Kotlin 范圍
- Kotlin Snake
- Kotlin Swing 教程
- Kotlin 字符串
- Kotlin 列表
- Kotlin 映射
- Kotlin 集合
- Kotlin 控制流程
- Kotlin 寫入文件
- Kotlin 讀取文件教程
- Kotlin 正則表達式
- ZetCode 其它教程
- TCL 教程
- Tcl
- Tcl 語法結構
- Tcl 中的基本命令
- Tcl 中的表達式
- Tcl 中的控制流
- Tcl 中的字符串
- Tcl 列表
- Tcl 中的數組
- Tcl 中的過程
- 輸入&輸出
- AWK 教程
- Vaadin 教程
- Vaadin 框架介紹
- Vaadin Grid教程
- Vaadin TextArea教程
- Vaadin ComboBox教程
- Vaadin Slider教程
- Vaadin CheckBox教程
- Vaadin Button教程
- Vaadin DateField教程
- Vaadin Link教程
- ZetCode PHP 教程
- PHP 教程
- PHP
- PHP 語法結構
- PHP 基礎
- PHP 數據類型
- PHP 字符串
- PHP 運算符
- PHP 中的控制流
- PHP 數組
- PHP 數組函數
- PHP 中的函數
- PHP 正則表達式
- PHP 中的面向對象編程
- PHP 中的面向對象編程 II
- PHP Carbon 教程
- PHP Monolog 教程
- PHP 配置教程
- PHP Faker 教程
- Twig 教程
- Valitron 教程
- Doctrine DBAL QueryBuilder 教程
- PHP Respect 驗證教程
- PHP Rakit 驗證教程
- PHP PDO 教程
- CakePHP 數據庫教程
- PHP SQLite3 教程
- PHP 文件系統函數
- ZetCode Python 教程
- Python 教程
- Python 語言
- 交互式 Python
- Python 語法結構
- Python 數據類型
- Python 字符串
- Python 列表
- Python 字典
- Python 運算符
- Python 關鍵字
- Python 函數
- Python 中的文件
- Python 中的面向對象編程
- Python 模塊
- Python 中的包
- Python 異常
- Python 迭代器和生成器
- Python 內省
- Python Faker 教程
- Python f 字符串教程
- Python bcrypt 教程
- Python 套接字教程
- Python smtplib教程
- OpenPyXL 教程
- Python pathlib教程
- Python YAML 教程
- Python 哈希教程
- Python ConfigParser教程
- Python 日志教程
- Python argparse 教程
- Python SQLite 教程
- Python Cerberus 教程
- Python PostgreSQL 教程
- PyMongo 教程
- PyMySQL 教程
- Peewee 教程
- pyDAL 教程
- pytest 教程
- Bottle 教程
- Python Jinja 教程
- PrettyTable 教程
- BeautifulSoup 教程
- pyquery 教程
- Python for循環
- Python 反轉
- Python Lambda 函數
- Python 集合
- Python 映射
- Python CSV 教程-讀寫 CSV
- Python 正則表達式
- Python SimpleJson 教程
- SymPy 教程
- Pandas 教程
- Matplotlib 教程
- Pillow 教程
- Python FTP 教程
- Python Requests 教程
- Python Arrow 教程
- Python 列表推導式
- Python 魔術方法
- PyQt 中的QPropertyAnimation
- PyQt 中的QNetworkAccessManager
- ZetCode Ruby 教程
- Ruby 教程
- Ruby
- Ruby 語法結構
- Ruby 基礎
- Ruby 變量
- Ruby 中的對象
- Ruby 數據類型
- Ruby 字符串
- Ruby 表達式
- Ruby 控制流
- Ruby 數組
- Ruby 哈希
- Ruby 中的面向對象編程
- Ruby 中的面向對象編程 II
- Ruby 正則表達式
- Ruby 輸入&輸出
- Ruby HTTPClient教程
- Ruby Faraday 教程
- Ruby Net::HTTP教程
- ZetCode Servlet 教程
- 從 Java Servlet 提供純文本
- Java Servlet JSON 教程
- Java Servlet HTTP 標頭
- Java Servlet 復選框教程
- Java servlet 發送圖像教程
- Java Servlet JQuery 列表教程
- Servlet FreeMarker JdbcTemplate 教程-CRUD 操作
- jQuery 自動補全教程
- Java servlet PDF 教程
- servlet 從 WAR 內讀取 CSV 文件
- Java HttpServletMapping
- EasyUI datagrid
- Java Servlet RESTFul 客戶端
- Java Servlet Log4j 教程
- Java Servlet 圖表教程
- Java ServletConfig教程
- Java Servlet 讀取網頁
- 嵌入式 Tomcat
- Java Servlet 分頁
- Java Servlet Weld 教程
- Java Servlet 上傳文件
- Java Servlet 提供 XML
- Java Servlet 教程
- JSTL forEach標簽
- 使用 jsGrid 組件
- ZetCode Spring 教程
- Spring @Bean注解教程
- Spring @Autowired教程
- Spring @GetMapping教程
- Spring @PostMapping教程
- Spring @DeleteMapping教程
- Spring @RequestMapping教程
- Spring @PathVariable教程
- Spring @RequestBody教程
- Spring @RequestHeader教程
- Spring Cookies 教程
- Spring 資源教程
- Spring 重定向教程
- Spring 轉發教程
- Spring ModelAndView教程
- Spring MessageSource教程
- Spring AnnotationConfigApplicationContext
- Spring BeanFactoryPostProcessor教程
- Spring BeanFactory教程
- Spring context:property-placeholder教程
- Spring @PropertySource注解教程
- Spring @ComponentScan教程
- Spring @Configuration教程
- Spring C 命名空間教程
- Spring P 命名空間教程
- Spring bean 引用教程
- Spring @Qualifier注解教程
- Spring ClassPathResource教程
- Spring 原型作用域 bean
- Spring Inject List XML 教程
- Spring 概要文件 XML 教程
- Spring BeanDefinitionBuilder教程
- Spring 單例作用域 bean
- 獨立的 Spring 應用
- 經典 Spring 應用中的JdbcTemplate
- Spring EmbeddedDatabaseBuilder教程
- Spring HikariCP 教程
- Spring Web 應用簡介
- Spring BeanPropertyRowMapper教程
- Spring DefaultServlet教程
- Spring WebSocket 教程
- Spring WebJars 教程
- Spring @MatrixVariable教程
- Spring Jetty 教程
- Spring 自定義 404 錯誤頁面教程
- Spring WebApplicationInitializer教程
- Spring BindingResult教程
- Spring FreeMarker 教程
- Spring Thymeleaf 教程
- Spring ResourceHandlerRegistry教程
- SpringRunner 教程
- Spring MockMvc 教程
- ZetCode Spring Boot 教程
- Spring Boot 發送電子郵件教程
- Spring Boot WebFlux 教程
- Spring Boot ViewControllerRegistry教程
- Spring Boot CommandLineRunner教程
- Spring Boot ApplicationReadyEvent 教程
- Spring Boot CORS 教程
- Spring Boot @Order教程
- Spring Boot @Lazy教程
- Spring Boot Flash 屬性
- Spring Boot CrudRepository 教程
- Spring Boot JpaRepository 教程
- Spring Boot findById 教程
- Spring Boot Data JPA @NamedQuery教程
- Spring Boot Data JPA @Query教程
- Spring Boot Querydsl 教程
- Spring Boot Data JPA 排序教程
- Spring Boot @DataJpaTest教程
- Spring Boot TestEntityManager 教程
- Spring Boot Data JPA 派生的查詢
- Spring Boot Data JPA 查詢示例
- Spring Boot Jersey 教程
- Spring Boot CSV 教程
- SpringBootServletInitializer教程
- 在 Spring Boot 中加載資源
- Spring Boot H2 REST 教程
- Spring Boot RestTemplate
- Spring Boot REST XML 教程
- Spring Boot Moustache 教程
- Spring Boot Thymeleaf 配置
- Spring Boot 自動控制器
- Spring Boot FreeMarker 教程
- Spring Boot Environment
- Spring Boot Swing 集成教程
- 在 Spring Boot 中提供圖像文件
- 在 Spring Boot 中創建 PDF 報告
- Spring Boot 基本注解
- Spring Boot @ResponseBody教程
- Spring Boot @PathVariable教程
- Spring Boot REST Data JPA 教程
- Spring Boot @RequestParam教程
- Spring Boot 列出 bean
- Spring Boot @Bean
- Spring Boot @Qualifier教程
- 在 Spring Boot 中提供靜態內容
- Spring Boot Whitelabel 錯誤
- Spring Boot DataSourceBuilder 教程
- Spring Boot H2 教程
- Spring Boot Web JasperReports 集成
- Spring Boot iText 教程
- Spring Boot cmd JasperReports 集成
- Spring Boot RESTFul 應用
- Spring Boot 第一個 Web 應用
- Spring Boot Groovy CLI
- Spring Boot 上傳文件
- Spring Boot @ExceptionHandler
- Spring Boot @ResponseStatus
- Spring Boot ResponseEntity
- Spring Boot @Controller
- Spring Boot @RestController
- Spring Boot @PostConstruct
- Spring Boot @Component
- Spring Boot @ConfigurationProperties教程
- Spring Boot @Repository
- Spring Boot MongoDB 教程
- Spring Boot MongoDB Reactor 教程
- Spring Boot PostgreSQL 教程
- Spring Boot @ModelAttribute
- Spring Boot 提交表單教程
- Spring Boot Model
- Spring Boot MySQL 教程
- Spring Boot GenericApplicationContext
- SpringApplicationBuilder教程
- Spring Boot Undertow 教程
- Spring Boot 登錄頁面教程
- Spring Boot RouterFunction 教程
- ZetCode Symfony 教程
- Symfony DBAL 教程
- Symfony 表單教程
- Symfony CSRF 教程
- Symfony Vue 教程
- Symfony 簡介
- Symfony 請求教程
- Symfony HttpClient教程
- Symfony Flash 消息
- 在 Symfony 中發送郵件
- Symfony 保留表單值
- Symfony @Route注解教程
- Symfony 創建路由
- Symfony 控制臺命令教程
- Symfony 上傳文件
- Symfony 服務教程
- Symfony 驗證教程
- Symfony 翻譯教程