既然我们是要实现从数据库里读取任务列表这个需求,那么首先我们就得知道如何通过编程的方式从数据库里把数据读出来。这里我们就选 PHP 作为我们的编程语言来实现我们的想法。
为什么是 PHP 呢?主要有以下两个原因:
PHP 比较简单,入门容易特别适合教学
全世界十个网站大概有八个都是 PHP 做的,所以市场还是有的
PHP 的历史也很长了,年纪大意味着稳定,但不一定意味着过时,PHP 最近一段时间还在新增功能,而且变化很快
当然作为『全栈』工程师,我们要接触的语言是很多的,后面还会遇到,但当你接触多了之后,就会发现语言跟语言之间还是有很多相通的地方,当你熟悉其中一个的时候,学起另外的就会快很多。
到目前为止我们已经知道两种语言了,HTML 和 SQL,只不过这俩语言是属于只服务于自己专业领域的语言,比如 SQL 就是用来操作数据库的,HTML 就是用来表示页面数据的。而有些编程语言适用性就更广一些,能解决各种各样的问题,这种语言就叫做 General Programming Language,简称 GPL,PHP 将是我们了解到的第三个语言,也是第一个 GPL。
就好像 HTML 需要浏览器来执行,SQL 需要通过 MySQL 来执行一样,PHP 也需要一个叫『PHP 解释器』的软件来执行。在 Ubuntu 里我们可以很方便得安装它
sudo apt install php-cli
# 我们也可以通过以下命令安装,但会安装很多我们用不到的组件,所以不太建议
sudo apt install php
提示安装完毕之后,我们可以通过下面的命令确认一下:
php -v
如果安装没有问题,会提示 PHP 解释器当前的版本。一般来说,PHP 的版本会显示为 PHP 7 以上。对于目前的项目需求来说,PHP 7.0 就已经足够我们用了。
这里要说明一下,因为 PHP 操作 MySQL 服务是一个可选功能,可能默认是不会安装的,所以我们要先检查一下是否支持连 MySQL。PHP 是通过 pdo_mysql 模块来连接 MySQL 的,我们可以通过下面的命令来查看 PHP 已经加载的模块(参数 -m 即 modules 的意思)
php -m
不出意外应该会返回一堆默认被安装的模块的名称,这些模块都是干嘛的先不用去管,现在的重点只是确认 pdo_mysql 模块在不在就行了。
这里顺便跟大家分享一个 Linux 里的命令或者说工具叫 grep,基本上所有发行版安装好都自带的。它的作用就是查找某个文字流里有没有出现某个指定的字符。最常见的文字流就是文件了,如果我想查找文件 index.html 里有没有出现 html 这个单词,就可以通过以下命令快速知道结果:
grep html index.html
大家可以通过 grep --help,或者 man grep 命令(man 是 manual 的意思即手册),或者就在网上查 grep 的所有用法,查多个文件,查某个目录下所有文件,给关键词加颜色(有些发行版默认就加了)等很多功能都是提供的。
通过 grep 这个特性,我们可以不用对着 PHP 返回的一堆模块看瞎了眼。但问题是 grep 只能找文件,如何用在 PHP 返回的结果里呢?
答案是在 *nix 系统里,我们可以将文件理解成文字流输入源,另外我们也可以通过『转发』操作,也就是 |,将 A 程序的输出,转成 B 程序的输入:
php -m|grep pdo_mysql
如果 PHP 加载了 pdo_mysql 模块,就应该返回 pdo_mysql。
如果我们发现 pdo_mysql 没有安装,那么我们可以通过下面的命令安装就行
sudo apt install php-mysql
开始第一个 PHP 程序
不过且慢,我们先回到当前 Ubuntu 账户的 home 目录
cd
Home 就是『家』这大家应该都知道,那么家之外就属于公共环境了,就跟你不应该在公共环境放自己的家具一样,我们也不应该在 home 之外的目录乱放文件。
你可以通过下面的命令确认是否在自己的 home 目录下:
pwd
pwd 就是 Print Working Directory 的意思,即打印当前的工作目录,正常情况下,你现在应该在 /home/你的用户名/ 这个目录里。
mkdir 是 MaKe DIRectory 的意思,即创建文件夹,我们先给自己创建一个名叫 code 的文件夹,或者说目录,当成我们的项目根目录。当然你也可以自己起名字
mkdir code
为了确认是否创建目录成功,我们可以通过『列文件(夹)』命令 ls (即 LiSt),列出当前目录下都有啥
ls
ls 命令也有很多参数,比如最常见的有 -l 即 long,没错,也就是更长(详尽)的信息,这里就不展示了,可以自己试试。
在 Linux 里还有 alias 即『别名』这个概念,可以把一些命令取一个别名,一般来说都是把长命令变成短别名。有好多发行版会默认将 ls -l 命令添加别名为 ll,大家也可以尝试一下自己的发行版是不是也是这样的。另外大家也可以通过 alias 命令列出当前所有的别名,或者新增别名:
# 列出所有别名
alias
# 新增别名
alias llh='ls -lh'
非 PHP 的话题不再展开。我们先进入项目根目录即 code 目录,然后使用 touch 命令创建一个文件 index.php,接着用大家自己喜欢的编辑器打开它,当然为了演示方便,我这里就用 Ubuntu 自带的,用起来跟 Windows 下记事本差不多的编辑器 gedit(实际上 gedit 功能要比 notepad 多多了)。
cd code
touch index.php
gedit index.php
我们在 gedit 里添加如下代码:
Hello world
保存之后,切换会终端,并运行以下命令:
php index.php
如果你能看到 Hello world,恭喜,您的第一个 PHP 程序已经能成功运行了。
是不是觉得,这什么玩意儿,我也没写啥啊?
我们再回到编辑器,将内容稍作添加:
Hello world
echo 'Bye world';
?>
再次回到终端运行脚本,返回的内容就是两行 xxx world 了。
这里我们可以做一个小总结,在 PHP 代码里,在 <?php和 ?>之间的代码,是 PHP 解释器要当作代码来处理的,而在之外的代码,PHP 解释器只是原样输出。
接下来我们将跳过一般教材特别无聊的基本概念介绍,直接说如何从数据库里读取数据,下面是从数据库读数据的代码,切记不要跳过注释
// 此为 PHP 里的注释
/* 也可以这么写注释 */
// Pdo 是一个『类』,对一个类做 new 操作,会变成一个『对象』
$pdo = new Pdo('mysql:dbname=minetodo', 'root', '123456');
// 我们可以把 $pdo 理解成之前我们用的 mysql 客户端,而 query 『方法』就跟在 mysql 客户端里执行 SQL 是一样的意思。
$rows = $pdo->query('select * from task');
// 大家可以先猜猜 foreach 是什么意思
foreach ($rows as $row) {
// var_dump 『函数』,可以将某个『变量』里的数据格式详细打印出来
var_dump($row);
}
// 如果后面不需要输出别的内容,PHP 代码关闭记号是可以省略不写的,建议不写,原因以后会说
这里我不会对什么是类,什么是函数,什么是方法给你们总结,那都是我的总结,不是你们自己的,学习最好的方式依然是从例子中去感受。如果你就想看别人的总结,网上也有很多很多,这里就不重复重复再重复了。
这里我们先重点看这一行
$pdo = new Pdo('mysql:dbname=minetodo', 'root','123456');
是不是感觉跟用 mysql-client 链接 MySQL 服务的命令很类似?让我们再回忆一下:
mysql -u root -p 123456
还记得我说如果没有设置密码,就不需要 -p 参数吗?PHP 代码是一样的,如果没设置密码,就不用写第三个参数,直接这样就行
$pdo = new Pdo('mysql:dbname=minetodo', 'root');
可能有些爱发问的小伙伴会问第一个参数为什么是那样写,我这里只先简单介绍一下,PDO (即 PHP Data Objects,PHP 数据对象)不仅可以支持 MySQL,其他很多种类的数据库都是支持的,比如之前提过的 SQLite,他也是支持的。它的第一个参数叫 DSN,即 Data Source Name,数据源名,DSN 包含了要连接的数据库类型,以及数据库地址等信息。比如例子里写的就是『数据库是 MySQL 类型,库名,即 dbname,是 minetodo』。假如我们的数据库是 SQLite 并且数据库文件是 minetodo.db,我们也可以写成
$pdo = new Pdo('sqlite:///minetodo.db');
注意上面例子连用户名都去掉了,因为 SQLite 不需要用户名(以及密码)。
还记得我们的需求吗?其中有一个需求是,在命令行下可以列出任务。在不知不觉中,我们已经完成了这个一个需求:
php index.php
当然我们会发现 var_dump 函数所打印出来的数据信息,过于详细:
array(4) {
["content"]=>
string(15) "第一条任务"
[0]=>
string(15) "第一条任务"
["created_at"]=>
string(19) "2020-01-29 22:36:10"
[1]=>
string(19) "2020-01-29 22:36:10"
}
var_dump 告诉我们,$row 是一个数组(array),在 PHP 里,获取数组中某个元素,可以通过以下方式,比如我们要获取 content 字段:
$row['content']
所以我们可以将返回的内容做的更美观一些,修改我们的 index.php 中 foreach 部分代码:
foreach ($rows as $row) {
echo $row['content'], ' @ ', $row['created_at'], PHP_EOL;
}
小技巧:echo 若干字符串,并且用 , 隔开,等同于
echo $row['content'];
echo ' @ ';
echo $row['created_at'];
echo PHP_EOL;
最后的 PHP_EOL 是『常量』,常量可以自己创建,习惯全大写,PHP 也自带许多常量,比如 PHP_EOL 表示『回车符』。常量常用来表示一个永恒不变的值,比如圆周率,但 PHP_EOL 实际上会根据运行的环境不同而变化:*nix 下它是 \n,而 Windows 下它是 \r\n。
关于回车符多说几句,在 *nix 里回车是一个字符 \n,而 Windows 下是两个字符 \r\n,因为这个差别,经常会出现以 Windows 为开发系统的工程师,在打开以 *nix 为开发系统的工程师发过来的文件后发现折行都没了。或者反过来,*nix 工程师会发现 Windows 工程师发过来的文件每行后面总是有乱码。其实团队成员在不同的操作系统下开发没有问题,问题是大家不去统一代码规范。实际上,大部分编辑器比如 gedit,都是可以设置行结尾字符是 *nix 风格还是 Windows 风格(有的写作 MS-DOS 风格,毕竟在更早的 DOS 时代就已经是这样了),当然像 Windows 记事本这种功能实在太简单,是不提供这种功能的,所以用 Windows 的同学最好还是换一个编辑器。
最终完整的代码看这里。注意实例代码是没有 MySQL 密码的,如果你设置了密码需要自行加上。
写作累,服务器还越来越贵
求分担,祝愿好人一生平安
天使打赏人