当前位置: 首页 > 后端技术 > PHP

DockerPHP入门实践(三)

时间:2023-03-30 02:35:35 PHP

第三章创建ThinkPHP应用在本教程的剩余部分,我们将完成一个基于ThinkPHP框架的天气查询应用。使用高德开放平台-天气查询的接口来实现我们的功能。查询数据缓存在MySql中,无需每次都频繁请求第三方接口(有请求次数限制)。选择高德开放平台-天气查询API的主要原因是免费。当然你也可以使用其他第三方的天气查询接口,看个人喜好。该应用是一个非常简单的RESTAPI应用,主要实现了两个接口。GET/weather/:location_id-从数据库中获取天气(如果存在),或者从第三方API(如果不存在)获取。DELETE/weather/:location_id-从数据库中删除缓存的天气信息。再次查询该位置的天气时,会从高德的天气界面获取。在我们编写应用程序之前,首先使用Docker安装并运行[ThinkPHP](https://www.kancloud.cn/manual/thinkphp6_0/1037479)来安装ThinkPHP框架ThinkPHP是一个免费开源,快速简单的面向对象轻量级轻量级PHP开发框架,为敏捷WEB应用开发,简化企业应用开发而生。ThinkPHP自诞生以来一直秉承简单实用的设计原则,在保持卓越性能和极简代码的同时,更注重易用性。在Apache2开源许可协议下发布意味着您可以免费使用ThinkPHP,甚至允许您将基于ThinkPHP开发的应用程序作为开源或商业产品发布/销售。这就是为什么我选择它作为本教程的教学框架。我不想让你因为一个框架而放弃,但我也不想一切都从头开始构建,因为本教程的重点是Docker,而不是我们的PHP应用程序。使用Docker创建ThinkPHP应用程序实际上比在本地配置PHP环境需要更少的操作。而且因为我们还需要使用Composer,多亏了Docker,我们甚至不需要在主机上安装它。首先打开你的终端并创建一个项目目录。$mkdirdocker-app并cd进入该目录$cddocker-app现在使用[官方ComposerDocker镜像](https://hub.docker.com/_/comp…)安装ThinkPHP。$dockerrun--rm--interactive--tty-vE:/workplace/docker-app/:/appcomposer:latestcreate-projecttopthink/thinkweather-app如果你查看weather-app/目录,你会看到进入ThinkPHP6的项目目录,如下:dirE:\workplace\docker-app\weather-appdirectory2022/02/1116:31

.2022/02/1116:30..2021/12/1621:06231.example.env2021/12/1621:0634.gitignore2021/12/1621:062,038.travis.yml2021/12/1621:06app2021/12/1621:061,094composer.json2022/02/1116:3136,134composer.lock2021/12/1621:06config2021/12/1621:06extend2021/12/1621:061,822许可证。txt2021/12/1621:06public2021/12/1621:061,459README.md2021/12/1621:06route2021/12/1621:06runtime2021/12/1621:06180薄k2022/02/1116:31vendor2021/12/1621:06view创建ThinkPHP应用过程中的命令整理我们的docker运行命令和第二章类似,但是我们使用的不同镜像我们不使用运行hello.php脚本的PHP镜像,而是使用Composer镜像。让我们看看发生了什么变化。composer:latest-这表示我们在此容器中使用的图像。如果需要,您可以指定特定版本的Composer;只需在DockerHub上查看支持的图像标签列表。create-projecttopthink/thinkweather-app-这是实际将ThinkPHP6安装到容器工作目录中的命令。因为该工作目录是我们主机目录的一个卷,所以由composer安装的文件现在同时存在于主机和容器中。此时,您的应用程序实际上并没有执行任何操作,但已经安装了ThinkPHP6,我们现在对composer如何在Docker中使用PHP有了一些了解。新建路由和Controller(逻辑处理)文件项目创建完成后,我们需要添加几个路由URL和Controller文件。我们打开weather-app目录下的app/controller,新建一个Weather.php文件,内容如下:request->param('location_id');}publicfunctiondelete(){//todoecho"location_idis".$this->request->param('location_id');然后打开weather-app目录下的app/route,在app.php文件中添加如下内容:Route::get('/weather/:location_id','weather/get');Route::delete('/天气/:location_id','天气/删除');运行我们的应用程序现在我们可以在Docker容器中运行我们的应用程序,只是为了验证我们的程序是否正常工作,因为我们只添加了两个路由URL。打开命令行并运行。$dockerrun--privileged=true--rm-p38000:80-vE:/workplace/docker-app/:/var/www/htmlphp:apache现在,在浏览器中打开http://localhost:38000/weather-app/public/index.php/weather/1,您应该会看到一个包含以下文本的空白页面:location_idis1恭喜,您刚刚成功运行了您的第一个ThinkPHP应用程序。运行ThinkPHP应用的命令整理出来了。我们这次使用的dockerrun命令不同于我们之前运行hello.php脚本和composercreate-project的两个命令....原因是这次我们要获取包含Apache的最新版本的PHP这样我们就可以为我们的网络应用程序提供服务。让我们更详细地看一下新的命令部分。-p38000:80-这里我们定义容器和主机系统之间的端口映射。此命令表示Docker应将容器上的端口80映射到我们主机上的端口38000。您可以选择主机上的任何有效端口,但使用高端口(高于10000)可能是个好主意,因为在大多数标准机器上,许多较低的端口是为内置进程保留的。对于容器,您必须*使用端口80,因为这是运行Apache的Docker映像公开的端口。--privileged=true-是否在容器中使用root权限-vE:/workplace/docker-app/:/var/www/html-这次我们将代码从宿主机挂载到容器的/var/www/html目录。原因是PHPApache镜像提供来自该目录的代码。这是我们之前运行的PHP脚本之间的细微但关键的区别。请务必仔细阅读PHPDocker镜像官方文档,以免遗漏此类内容。php:apache-这个图像是官方的PHPApache容器。它在同一个容器中包含PHP和Apache(一种流行的Web服务器),使您可以快速为本地开发提供代码。当然你也可以选择使用php:fpm镜像链接一个nginx镜像。这些我不会在本书中介绍,需要你自己去了解。最后,您会注意到这次图像名称后没有命令。这可能会让新的Docker用户感到困惑,但默认情况下,大多数图像都会运行一些命令,即使您没有指定命令也是如此。对于PHPApache镜像,默认命令是运行shell脚本来启动Apache。这个脚本正是我们想要的,所以没有理由改变它。此时,您的终端将显示所有传入的Apache请求,因此当您加载第一个URL时,您可能会看到类似这样的内容。172.17.0.1--[11/Feb/2022:09:14:02+0000]"GET/weather-app/public/index.php/weather/1HTTP/1.1"200245"-""Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,如Gecko)Chrome/98.0.4758.80Safari/537.36Edg/98.0.1108.43"您可以通过向终端发送“中断”信号来停止和退出终端。在Windows上,这可以通过按Ctrl和按c来实现。更多Docker运行选项在分离模式下运行运行新Web应用程序的另一个选择是在“分离”模式下运行容器。这意味着您不会在终端中看到容器的输出。这可以通过在我们之前的命令中添加-d标志来实现。$dockerrun--privileged=true-d--rm-p38000:80-vE:/workplace/docker-app/:/var/www/htmlphp:apache停止容器在分离模式下启动容器后,您的终端将显示新容器的完整ID——类似于a70d25c2a7cedae673f8ab...如果您想停止此容器,您可以使用dockerstop命令,告诉Docker容器的ID。例如$dockerstopa70d25c2a7cedae673f8ab因为输入整个ID很麻烦,Docker允许您只输入前三个或更多字符(如果需要)。$dockerstopa70命名容器最后,我建议命名你的容器。我们在本书后面的许多示例中都这样做,因为通过名称记住容器比通过随机分配的ID更容易,而且ID是随机的,因此每次运行新版本的容器时,它都会得到一个新的ID。只要不存在同名的容器,就可以多次发布该名称。为了给我们的新应用程序容器命名,我们可以使用传入的--name标志重新创建它。$dockerrun--privileged=true-d--rm--name=weather-app-p38000:80-vE:/workplace/docker-app/:/var/www/htmlphp:apache正在使用dockerrun命令,还有更多可用选项,因此您可能需要更详细地阅读文档。在开发应用程序的其余部分时,我们将涉及其中一些选项。添加高德天气SDK下面我们来介绍一下高德的天气SDK。在使用SDK之前,您需要阅读高德开放平台-天气查询的技术文档。在添加SDK之前,我们必须首先确保所有现有的容器都已停止。$dockerps//运行上述命令后停止容器dockerstopcontainerID该命令将列出所有正在运行的容器。您还可以通过添加-a标志来查看已停止的容器。如果有任何容器正在运行,请在我们继续之前使用dockerstop停止它们。添加天气SDK执行命令添加高德天气SDK,欢迎点赞+star。这是作者之前打包好的SDK。当然你也可以自己重新打包或者使用其他的天气SDK。现在在你的终端上运行它:dockerrun--rm--interactive--tty-vE:/workplace/docker-app/weather-app:/appcomposer:latestrequireclydecn/php-amap-weather这个命令将安装项目中的新包。在此过程中,您应该会在终端中看到类似这样的输出。使用版本^1.0用于clydecn/php-amap-weather./composer.json已更新正在运行composerupdateclydecn/php-amap-weather正在加载带有包信息的作曲家存储库更新依赖项锁定文件操作:7次安装,0次更新,0次删除-锁定clydecn/php-amap-weather(v1.0.0)-锁定guzzlehttp/guzzle(6.5.5)-锁定guzzlehttp/promises(1.5.1)-锁定guzzlehttp/psr7(1.8.3)-锁定ralouphie/getallheaders(3.0.3)-Lockingsymfony/polyfill-intl-idn(v1.24.0)-Lockingsymfony/polyfill-intl-normalizer(v1.24.0)写锁文件从锁文件安装依赖包(包括require-dev)打包操作:7次安装,0次更新,0次删除-下载symfony/polyfill-intl-normalizer(v1.24.0)-下载symfony/polyfill-intl-idn(v1.24.0)-下载ralouphie/getallheaders(3.0.3)-下载guzzlehttp/psr7(1.8.3)-下载guzzlehttp/promises(1.5.1)-下载guzzlehttp/guzzle(6.5.5)-下载clydecn/php-amap-weather(v1.0.0)0/7[>-------------------------]0%-下载symfony/polyfill-intl-idn(v1.24.0)-下载ralouphie/getallheaders(3.0.3)-下载guzzlehttp/psr7(1.8.3)-下载clydecn/php-amap-weather(v1.0.0)-下载symfony/polyfill-intl-normalizer(v1.24.0)-下载guzzlehttp/promises(1.5.1)-下载guzzlehttp/guzzle(6.5.5)-安装symfony/polyfill-intl-normalizer(v1.24.0):提取档案-安装symfony/polyfill-intl-idn(v1.24.0):提取档案-安装ralouphie/getallheaders(3.0.3):提取档案-安装guzzlehttp/psr7(1.8.3):提取档案-安装guzzlehttp/promises(1.5.1):Extractingarchive-Installingguzzlehttp/guzzle(6.5.5):Extractingarchive-Installingclydecn/php-amap-weather(v1.0.0):Extractingarchive3软件包建议由新的依赖项添加,使用`composer苏格gest`查看详细信息。生成自动加载文件>@phpthinkservice:discoverSucceed!>@phpthinkvendor:publishFile/app/config/trace.php存在!成功!您正在使用的10个包正在寻找资金。使用`composerfund`命令以了解更多信息!现在SDK已经安装好了,可以使用了调用SDKAPI我们将使用新增的高德天气SDK完善我们的业务逻辑,打开controller目录下的Weather.php,添加如下内容:key="KEY";//搞得KEY$this->weather=newAmapWeather($this->key);}publicfunctionget(){$rid=$this->request->param('location_id','310000');//查询当前天气$res=$this->weather->getLiveWeather($rid);返回json($res,200);}publicfunctiondelete(){//todoecho"location_idis".$this->request->param('location_id');我们做了一些更新——主要是为了引入天气API来初始化天气类$this->weather=newAmapWeather($this->key);-实例化天气API类$res=$this->weather->getLiveWeather('310000');-获取天气信息。返回json($res,200);-最后,返回Json数据来测试我们的应用程序是否初步完成了向API传递真实位置ID并返回一些数据。首先,使用此AutoNavi位置查找来查找位置ID。我正在使用上海的ID进行测试。310000,当然你也可以直接传到上海。好的,让我们再次运行docker容器。dockerrun-d--privileged=true--rm--name=weather-app-p38000:80-vE:/workplace/docker-app/:/var/www/htmlphp:apache并在浏览器中访问在浏览器中运行的应用程序位于http://localhost:38000/weather-app/public/index.php/weather/310000。您应该会看到如下所示的JSON数据。{"status":"1","count":"1","info":"OK","infocode":"10000","lives":[{"province":"Shanghai","city":"Shanghai","adcode":"310000","weather":"Sunny","temperature":"11","winddirection":"East","windpower":"≤3","humidity":"38","re??porttime":"2022-02-1414:01:45"}]}您的DockerizedPHP应用程序现在从外部源返回真实数据并在Apache中提供它,但正如您可能注意到的那样,它不是这么快(我的页面加载时间是1.92秒!)。高德天气API是一项免费服务,其他国家可能无法访问。为了解决这个问题,我们将查询数据保存在自己的MySQL数据库中,下次访问时可以快速响应。这将大大提高性能,在下一章中我们将学习如何使用Docker将MySql与PHP应用程序结合起来。