PostgreSQL PHP 编程入门
最后修改于 2020 年 7 月 6 日
在 PostgreSQL PHP 教程的第一章中,我们将提供必要的定义。我们将展示如何安装 PostgreSQL 数据库和所需的软件包。这些示例将使用 PHP CLI 在命令行上运行。
为了运行这些示例,我们需要安装 PHP 语言(以 PHP CLI 的形式)和 PostgreSQL 数据库。我们还需要 php5-psql 包。
关于 PostgreSQL 数据库
PostgreSQL 是一个强大、开源的对象关系数据库系统。它是一个多用户数据库管理系统。它在多个平台上运行,包括 Linux、FreeBSD、Solaris、Microsoft Windows 和 Mac OS。PostgreSQL 由 PostgreSQL 全球开发小组开发。
设置 PostgreSQL
我们必须安装 PostgreSQL 数据库。
$ sudo apt-get install postgresql
在基于 Debian 的系统上,我们可以使用以上命令安装 PostgreSQL 数据库。
$ sudo update-rc.d -f postgresql remove Removing any system startup links for /etc/init.d/postgresql ... /etc/rc0.d/K21postgresql /etc/rc1.d/K21postgresql /etc/rc2.d/S19postgresql /etc/rc3.d/S19postgresql /etc/rc4.d/S19postgresql /etc/rc5.d/S19postgresql /etc/rc6.d/K21postgresql
如果我们从软件包安装 PostgreSQL 数据库,它会自动添加到操作系统的启动脚本中。如果我们只是学习使用数据库,则没有必要每次启动系统时都启动数据库。上面的命令会删除 PostgreSQL 数据库的任何系统启动链接。
$ /etc/init.d/postgresql status Running clusters: 9.1/main $ service postgresql status Running clusters: 9.1/main
我们检查 PostgreSQL 服务器是否正在运行。如果未运行,我们需要启动服务器。
$ sudo service postgresql start * Starting PostgreSQL 9.1 database server [ OK ]
在 Ubuntu Linux 上,我们可以使用 service postgresql start 命令启动服务器。
$ sudo service postgresql stop [sudo] password for janbodnar: * Stopping PostgreSQL 9.1 database server [ OK ]
我们使用 service postgresql stop 命令停止 PostgreSQL 服务器。
$ sudo -u postgres createuser janbodnar Shall the new role be a superuser? (y/n) n Shall the new role be allowed to create databases? (y/n) y Shall the new role be allowed to create more new roles? (y/n) n
我们在 PostgreSQL 系统中创建一个新角色。我们允许它具有创建新数据库的能力。一个*角色*是数据库世界中的一个用户。角色与操作系统用户是分开的。我们创建了一个新用户,没有使用 -W 选项,例如我们没有指定密码。这使我们能够使用此用户连接到数据库,而无需密码身份验证。请注意,这仅在 localhost 上有效。
$ sudo -u postgres createdb testdb -O janbodnar
createdb 命令创建一个新的 PostgreSQL 数据库,所有者为 janbodnar。
PHP CLI
众所周知,PHP 语言可以在 Web 服务器上运行。但它也可以在命令行上使用。PHP 命令行界面 (PHP CLI) 是一个库,允许程序员在命令行上使用 PHP。使用 PHP CLI,我们可以使用 PHP-GTK 构建 GUI 应用程序,或者我们可以创建简单的测试脚本。在本教程中,我们将使用命令行 PHP 解释器连接到 PostgreSQL 数据库。
$ sudo apt-get install php5-cli
我们在 Linux 系统上安装 PHP CLI 模块。
php5-pgsql 包
*php5-pgsql* 是一个用于从 PHP 语言使用 PostgreSQL 数据库的包。在其他系统上,包名可能不同。
$ sudo apt-get install php5-pgsql
我们启动上述命令来安装该包。
处理错误
我们对在 PHP 中处理错误做一个简短的说明。PHP 内置了对错误报告的支持。具体的设置可以在 php.ini 文件中控制。请注意,PHP CLI 版本有一个单独的 INI 文件。它位于我们的系统上的 /etc/php5/cli/php.ini 中。
display_errors 指令控制是否显示内置的错误消息。在开发环境中,会显示这些错误消息。在生产环境中,它们被抑制。没有理由向用户显示这些技术性消息。此外,这是一个潜在的安全风险。
通常,我们应该将更具体的错误消息记录到日志文件中。log_errors 指令控制是否记录错误。error_log 指定脚本错误应记录在哪个文件中的名称。如果未设置,则 PHP CLI 的默认值为 stderr。
pg_last_error 函数获取连接的最后一个错误消息字符串。它与内置错误报告中生成的错误消息相同。
在本教程的示例中,我们不使用 pg_last_error 函数,因为它会复制内置的错误消息。我们有以下设置
... display_errors = On ... log_errors = On ; Our own custom based log file error_log = /home/janbodnar/.phpcli_log ...
我们显示内置的错误;它们显示在命令行上。错误消息也会记录到指定的日志文件中。如果我们不希望在控制台上显示错误消息,我们只需关闭 display_errors 指令。
$rs = pg_query($con, $query) or die("Cannot execute query: $query\n");
在脚本中,我们使用 die 函数显示一个简单的错误消息,该消息很容易理解。更详细的细节被保存到日志文件中。die 函数也会终止脚本。
版本
在第一个代码示例中,我们将获取 PostgreSQL 数据库的版本。
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "testdb";
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
$query = "SELECT VERSION()";
$rs = pg_query($con, $query) or die("Cannot execute query: $query\n");
$row = pg_fetch_row($rs);
echo $row[0] . "\n";
pg_close($con);
?>
在上面的 PHP 脚本中,我们连接到之前创建的 testdb 数据库。我们执行一条 SQL 语句,该语句返回 PostgreSQL 数据库的版本。
$host = "localhost"; $user = "user12"; $pass = "34klq*"; $db = "testdb";
这些是连接字符串变量。要创建到 PostgreSQL 数据库的连接,我们必须提供主机名、用户名和密码以及数据库名称。
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
我们连接到数据库服务器。如果无法创建连接,则 die 函数终止脚本并将错误消息打印到控制台。pg_connect 函数返回一个连接资源,稍后将与其他模块函数一起使用。
$query = "SELECT VERSION()";
此 SQL 语句选择 PostgreSQL 数据库的版本。
$rs = pg_query($con, $query) or die("Cannot execute query: $query\n");
使用 pg_query 函数执行查询。
$row = pg_fetch_row($rs);
我们从返回的结果中获取数据。
echo $row[0] . "\n";
我们将检索到的数据打印到控制台。数据以 PHP 数组的形式返回。数组的第一个元素是我们正在寻找的字符串。
pg_close($con);
使用 pg_close 函数关闭到数据库的连接。
$ php version.php
PostgreSQL 9.1.3 on i686-pc-linux-gnu, compiled by gcc-4.6.real
(Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1, 32-bit
运行 version.php 脚本。
插入数据
我们将创建一个 cars 表并向其中插入几行。
<?php
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "testdb";
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
$query = "DROP TABLE IF EXISTS cars";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "CREATE TABLE cars(id INTEGER PRIMARY KEY, mame VARCHAR(25), price INT)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(1,'Audi',52642)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(2,'Mercedes',57127)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(3,'Skoda',9000)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(4,'Volvo',29000)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(5,'Bentley',350000)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(6,'Citroen',21000)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(7,'Hummer',41400)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(8,'Volkswagen',21606)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
pg_close($con);
?>
上面的脚本创建了一个 Cars 表并向该表中插入 8 行。
$query = "DROP TABLE IF EXISTS cars";
pg_query($con, $query) or die("Cannot execute query: $query\n");
如果 cars 表已存在,我们将其删除。pg_query 函数在指定的数据库连接上执行给定的查询。
$query = "CREATE TABLE cars(id INTEGER PRIMARY KEY, mame VARCHAR(25), price INT)";
此 SQL 语句创建一个新的 cars 表。该表有三列。
$query = "INSERT INTO cars VALUES(1,'Audi',52642)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
$query = "INSERT INTO cars VALUES(2,'Mercedes',57127)";
pg_query($con, $query) or die("Cannot execute query: $query\n");
我们正在向表中插入两辆车。
pg_close($con);
关闭到数据库的连接。
$ psql testdb psql (9.1.3) Type "help" for help. testdb=# 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 | 21606 9 | BMW | 36000 (9 rows)
我们使用 psql 工具验证写入的数据。
预处理语句
现在我们将关注预处理语句。当我们编写预处理语句时,我们使用占位符而不是直接将值写入语句中。预处理语句可以提高安全性和性能。
预处理语句是一个服务器端对象,可用于优化性能。当查询被预处理时,它会被解析、重写和计划。稍后只需执行预处理语句即可。因此,解析、重写和计划阶段仅执行一次,而不是每次执行语句时都执行。预处理语句仅持续当前数据库会话的持续时间。当会话结束时,预处理语句将被遗忘,因此在使用前必须重新创建。
$host = "localhost";
$user = "user12";
$pass = "34klq*";
$db = "testdb";
$id = 9;
$name = "BMW";
$price = 36000;
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
$query = "INSERT INTO cars VALUES($1, $2, $3)";
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
pg_execute($con, "prepare1", array($id, $name, $price))
or die ("Cannot execute statement\n");
echo "Row successfully inserted\n";
pg_close($con);
我们向 cars 表添加一行。我们使用预处理查询。
$id = 9; $name = "BMW"; $price = 36000;
我们有三个变量,将用于构建查询。这些值可能来自一个 Web 表单。
$query = "INSERT INTO cars VALUES($1, $2, $3)";
这是一个带有 $1、$2 和 $3 占位符的 SQL 查询。稍后将填充占位符。
pg_prepare($con, "prepare1", $query)
or die ("Cannot prepare statement\n");
在这里,我们通过调用 pg_prepare 函数来准备一个查询。函数的第二个参数是预处理语句的名称。它对于每个连接都必须是唯一的。预处理语句更快并且可以防止 SQL 注入攻击。
pg_execute($con, "prepare1", array($id, $name, $price))
or die ("Cannot execute statement\n");
pg_execute 函数发送一个请求,以使用给定参数执行预处理语句,并等待结果。这些值绑定到占位符。
$ php prepared.php Row successfully inserted testdb=# 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 | 21606 9 | BMW | 36000 (9 rows)
我们已向表中插入了一辆新车。
来源
本教程参考了 PostgreSQL PHP 手册 和 PostgreSQL 文档。
这是 PostgreSQL PHP 教程的介绍性章节。