PHP:使用curl请求聚合支付的驾考宝典题库接口数据, 并渲染到页面上;composer 常用的指令;mvc pathinfo 路由映射实现

一. API 基础知识

1. url 的相关知识

1.1 一切皆”请求”

常见的请求场景如下:

  • 搜索引擎查询信息
  • 商城通过物流接口获取快递状态
  • 微信通过支付回调 URL 通知用户支付情况
  • 调用运营商接口发送短信
  • 调用天气信息展示在 APP 或网站上
  • 调用百度 REST API 接口实现文字转语音,实现支付语音提示
  • 调用百度图片审核接口过滤非法色情图片
  • 调用地图接口展示附近指定商户

1.2 url 组成

任何请求都必须通过 url 发起

一个典型的 URL 格式如下:
http://hostname:80/path/demo.php/a/b/c/id/5/uname/peter?k1=v1&k2=v2#anchor
-https 端口443 ftp 端口21

  • http: 基于 http 协议的 url, 类似还有 https
  • hostname: 接收请求的服务器 ip 地址或主机名(域名)
  • 80: 端口号,如果省略则默认为 80
  • path: 脚本在服务器上的路径
  • index.php: 真正访问的脚本文件,实际上浏览器只关注到这个位置,后面的内容由服务器解释
  • a/b/c: PATH_INFO,一种附加参数的添加方式
  • ?后面的内容: k1=v1&k2=v2, 查询字符串,也是 url 附加参数,get 请求
  • anchor: 锚点,当前页面内跳转,可视为页面内部路由

  • parse_url()函数
  • demo1.php

2. Chrome 浏览器

全球开发者使用最多的是 Chrome 浏览器,所以我们也会使用它
Chrome 开发者工具面板

  • Elements: html,css…
  • console: 内置的 JavaScript 调试器,可编写简单的 js 代码
  • Sources: 网站中有哪些文件,图片等,可进行代码单步调试
  • Network: 查看浏览器发送了哪些请求,以及响应状态
  • Application: 查看 cookie,本地会话数据等
  • 目前先了解以上几个面板功能即可

3. url 编码

  • 百度搜索:php 中文网, 在 chrome 开发者工具 Network 中发现 php 后面的中文网变成了%E4%B8%...
  • 因为 url 仅允许数字/字母,以及部分特殊字符!*'();:@&=+$,/?#[],所以中文需要进行编码
  • 除了-_.之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号+
  • 此编码与表单 POST 数据的编码方式一样
  • 此编码与 enctype application/x-www-form-urlencoded 的媒体类型编码方式一样
  • urlencode()urldecode()
  • demo2.php

4. php 站点运行原理与访问流程

  1. 用户通过浏览器访问站点,如php.cn
  2. 浏览器将用户的 http 请求发送到php.cn站点所在的 web 服务器
  3. web 服务器监听 80 端口接受请求后,发现是 php 脚本自己不能直接处理
  4. web 服务器如已安装 php 扩展模块,则将请求转发给 php 模块(解释器)处理
  5. php 根据请求,从数据库/缓存/文件中读取数据,并生成对应的 html 页面
  6. php 模块将生成的页面转发给 web 服务器
  7. web 服务器将 php 生成的 html 页面做为 http 请求的响应返回到客户端
  8. 客户端浏览器将收到的 html,css,js 等进行解析渲染最终生成完整页面

图示:


5. 服务器端的各个角色

5.1 web 服务器

  • 主流: Apache / Nginx
  • 如果是请求的是静态资源,如 html,图片等, 则直接响应即可
  • 如果是动态请求(html 需要动态生成),则需要将请求转发给相应的扩展去处理

5.2 php 解释器

  • 做为 web 服务器的扩展模块, 负责解析处理 php 脚本
  • 生成 html 页面, 或者指定格式的字符串,如json

5.3 数据库

  • 动态网站的重要特征就是数据的动态生成
  • 数据库是网站数据的最佳保存方式
  • MySQL 数据库免费强大,是 PHP 的最佳拍档

5.4 缓存

  • 将用户经常请求的内容, 或者更新不频繁的数据缓存起来, 可加速请求响应速度
  • 当用户请求的数据已在缓存中时, 则不再进行数据库读写,而是直接从缓冲读取
  • 常用缓存方式: Redis, Memcached

5.5 文件

  • 并非所有数据都适合数据库或缓冲,例如数据库配置信息,使用文件保存更合适
  • 使用文件方式,直接用 php 脚本读取,省去数据库访问的开销,效率更高更灵活
  • 几乎所有框架或项目都会有一个config目录,就是这个原因

6. 场景介绍

  1. 本地环境: 本机安装全部开发组件,并通过Git提交供测试
  2. 测试环境: 通常是内网服务器,以节约成本
  3. 发布环境: 在创建与生产环境一致的环境, 导入真实数据线上测试
  4. 生产环境: 目标用户的环境,不允许再次测试,防止破坏用户数据

7. 本地环境

学习阶段, 学会搭建本地开发环境即可

  • 集成环境: phpStudy_pro
  • 编辑器: vscode
  • [选学]版本控制系统(VCS): Gitee(码云)

7.1 phpStudy

  • 下载: https://www.xp.cn/download.html
  • 配置本地域名: php.edu
  • 本地项目目录: WWW/php/
  • php 版本: 7.3+
  • web 服务器: Apache

Gitee

  • 创建帐号: https://gitee.com/
  • 安装 Git: https://git-scm.com/
  • Git 手册: https://git-scm.com/book/zh/v2
  1. script
  2. ### 初始化Git,创建本地版本库
  3. `cd php`
  4. `git init`
  5. ### 设置用户名和邮箱
  6. `git config --global user.name peter`
  7. `git config --global user.email peter@php.cn`
  8. ### 配置远程版本库
  9. `git remote add origin https://gitee.com/bnkt/php_edu.git`
  10. ### 查看远程库
  11. `git remote -v`
  12. ### 添加到暂存区
  13. `git add .`
  14. ### 提交到本地版本库
  15. `git commit -m 'first commit'`
  16. ### 查看本地状态
  17. `git status`
  18. ### 提交到远程版本库
  19. `git push origin master`
  20. ### 从远程仓库拉到项目到本地
  21. `git pull https://gitee.com/bnkt/php_edu.git`
  22. ### 从远程仓库克隆项目到本地
  23. `git clone https://gitee.com/bnkt/php_edu.git`
  24. ### 如果添加.gitignore不生效,要先清空本地缓存后再提交
  25. `git rm -r --cached`

①MVC pathinfo 路由映射

  • mvc这种架构模式 url地址都会映射到控制器下面的一个具体操作方法上

使用全局函数SERVER PATHINFO 获取url地址中的值,进行分解,最后映射到路由中

代码块

  1. <?php
  2. namespace mvc;
  3. class UserController
  4. {
  5. public function index()
  6. {
  7. return '<p>这是首页</p>';
  8. }
  9. }
  10. // var_dump($_SERVER['PATH_INFO']);
  11. //分割成数组,然后过滤空值,最后重置键
  12. $pathinfo = array_values(array_filter(explode('/',$_SERVER['PATH_INFO'])));
  13. //拼接成实例化的类
  14. $controller = __NAMESPACE__."\\".ucfirst(array_shift($pathinfo)).'Controller';
  15. $action = array_shift($pathinfo);
  16. echo call_user_func([(new $controller),$action]);

②MVC pathinfo 拼接?后面的参数

  • http://php.edu/0518/api/demo1.php/user/index/id/3/name/peter 从 url中提取参数 参数也是通过path_info方式提供

代码块

  1. <?php
  2. namespace mvc;
  3. class UserController
  4. {
  5. public function index($id,$name)
  6. {
  7. return "你好 $name , 你的id是 $id";
  8. return '<p>这是首页</p>';
  9. }
  10. }
  11. // var_dump($_SERVER['PATH_INFO']);
  12. //分割成数组,然后过滤空值,最后重置键
  13. $pathinfo = array_values(array_filter(explode('/',$_SERVER['PATH_INFO'])));
  14. //拼接成实例化的类
  15. $controller = __NAMESPACE__."\\".ucfirst(array_shift($pathinfo)).'Controller';
  16. $action = array_shift($pathinfo);
  17. //http://php.edu/0518/api/demo1.php/user/index/id/3/name/peter 从 url中提取参数 参数也是通过path_info方式提供
  18. //创建一个空数组,把过滤的值放到空数组中
  19. $params = [];
  20. for ($i=0; $i <count($pathinfo) ; $i+=2) {
  21. if (isset($pathinfo[$i+1]) && !empty($pathinfo[$i+1])) {
  22. $params[$pathinfo[$i]] = $pathinfo[$i+1];
  23. }
  24. }
  25. echo call_user_func_array([(new $controller),$action],$params);

二.请求聚合支付的天气预报/驾考宝典题库接口数据

①天气预报

天气预报代码块

  1. <?php
  2. //请求天气预报接口
  3. //curl 初始化 获取一个curl句柄 发起http请求
  4. $url = 'http://apis.juhe.cn/simpleWeather/query?';
  5. $key = 'eb8f148b35bb2f22c3fd59804f58084c';
  6. $city = '上海';
  7. //http_build_query — 生成 URL-encode 之后的请求字符串
  8. $query = http_build_query(['key'=>'eb8f148b35bb2f22c3fd59804f58084c','city'=>'上海']);
  9. //curl_init — 初始化 cURL 会话
  10. $ch = curl_init();
  11. //curl_setopt — 设置 cURL 传输选项
  12. //CURLOPT_URL 需要获取的 URL 地址,也可以在curl_init() 初始化会话的时候。
  13. curl_setopt($ch,CURLOPT_URL,$url.$query);
  14. //CURLOPT_HTTPGET true 时会设置 HTTP 的 method 为 GET,由于默认是 GET,所以只有 method 被修改时才需要这个选项。
  15. curl_setopt($ch,CURLOPT_HTTPGET,true);
  16. //CURLOPT_HEADER 启用时会将头文件的信息作为数据流输出。
  17. curl_setopt($ch,CURLOPT_HEADER,false);
  18. //CURLOPT_RETURNTRANSFER true 将curl_exec()获取的信息以字符串返回,而不是直接输出。
  19. curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
  20. // 抓取URL并把它传递给浏览器
  21. $apiData = curl_exec($ch);
  22. //关闭cURL资源,并且释放系统资源
  23. curl_close($ch);
  24. ?>
  25. <!DOCTYPE html>
  26. <html lang="en">
  27. <head>
  28. <meta charset="UTF-8">
  29. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  30. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  31. <title>Document</title>
  32. </head>
  33. <style>
  34. table {
  35. color: #555;
  36. background-color: #efefef;
  37. border-collapse: collapse;
  38. width: 600px;
  39. text-align: center;
  40. margin: auto;
  41. }
  42. td {
  43. border: 2px solid #FFF;
  44. padding: 5px;
  45. }
  46. table caption {
  47. font-size: 1.2rem;
  48. margin-bottom: 15px;
  49. }
  50. table thead tr:first-of-type {
  51. background-color: darkturquoise;
  52. color: white;
  53. }
  54. </style>
  55. <body>
  56. <script>
  57. const obj = <?=$apiData?>;
  58. // console.log(obj);
  59. // 创建表格元素
  60. const table = document.createElement('table');
  61. // 表头: 城市 + 标题, 如:上海天气预报
  62. table.createCaption().textContent = obj.result.city + '天气预报';
  63. // 创建表头,并尾部添加新行,将表头参数填入
  64. const tr = table.createTHead().insertRow(-1);
  65. tr.insertCell(0).innerText = '日期';
  66. tr.insertCell(1).innerText = '气温';
  67. tr.insertCell(2).innerText = '雨雪';
  68. tr.insertCell(3).innerText = '风向';
  69. // 遍历未来几天的天气对象数组
  70. obj.result.future.forEach(item => {
  71. // 生成一个新行,并插入到表尾
  72. const row = table.insertRow(-1);
  73. // 转日期格式
  74. let date = new Date(Date.parse(item.date.replace(/-/g, '/')));
  75. // 组装成符合国人阅读习惯的格式
  76. let timeStr = `${date.getFullYear()}年${date.getMonth()+1}月${date.getDate()}日`;
  77. // 遍历每一天的天气对象数组,并填充到生成的单元格中
  78. row.insertCell(0).innerText = timeStr;
  79. row.insertCell(1).innerText = item.temperature;
  80. row.insertCell(2).innerText = item.weather;
  81. row.insertCell(3).innerText = item.direct;
  82. // 将生成的该行插入到表格元素中
  83. table.appendChild(row);
  84. });
  85. // 最后将表格添加到页面中
  86. document.body.appendChild(table);
  87. </script>
  88. </body>
  89. </html>

②驾考宝典

驾考宝典代码块

  1. <?php
  2. //请求天气预报接口
  3. //curl 初始化 获取一个curl句柄 发起http请求
  4. $url = 'http://v.juhe.cn/jztk/query?';
  5. $key = '304dde4f5025a4d6eec392b0c15fcb1b';
  6. $subject = 1;
  7. $model = 'c2';
  8. $testType = 'rand';
  9. //http_build_query — 生成 URL-encode 之后的请求字符串
  10. $query = http_build_query([
  11. 'subject'=>1,'model'=>'c2',
  12. 'testType' =>'rand',
  13. 'key'=>'304dde4f5025a4d6eec392b0c15fcb1b',
  14. ]);
  15. //curl_init — 初始化 cURL 会话
  16. $ch = curl_init();
  17. //curl_setopt — 设置 cURL 传输选项
  18. //CURLOPT_URL 需要获取的 URL 地址,也可以在curl_init() 初始化会话的时候。
  19. curl_setopt($ch,CURLOPT_URL,$url.$query);
  20. //CURLOPT_HTTPGET true 时会设置 HTTP 的 method 为 GET,由于默认是 GET,所以只有 method 被修改时才需要这个选项。
  21. curl_setopt($ch,CURLOPT_HTTPGET,true);
  22. //CURLOPT_HEADER 启用时会将头文件的信息作为数据流输出。
  23. curl_setopt($ch,CURLOPT_HEADER,false);
  24. //CURLOPT_RETURNTRANSFER true 将curl_exec()获取的信息以字符串返回,而不是直接输出。
  25. curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
  26. // 抓取URL并把它传递给浏览器
  27. $apiData = curl_exec($ch);
  28. //关闭cURL资源,并且释放系统资源
  29. curl_close($ch);
  30. ?>
  31. <!DOCTYPE html>
  32. <html lang="en">
  33. <head>
  34. <meta charset="UTF-8">
  35. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  36. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  37. <title>Document</title>
  38. </head>
  39. <style>
  40. table {
  41. color: #555;
  42. background-color: #efefef;
  43. border-collapse: collapse;
  44. width: 600px;
  45. text-align: center;
  46. margin: auto;
  47. }
  48. td {
  49. border: 2px solid #FFF;
  50. padding: 5px;
  51. }
  52. table caption {
  53. font-size: 1.2rem;
  54. margin-bottom: 15px;
  55. }
  56. table thead tr:first-of-type {
  57. background-color: darkturquoise;
  58. color: white;
  59. }
  60. </style>
  61. <body>
  62. <img src="" alt="">
  63. <script>
  64. const obj = <?=$apiData?>;
  65. console.log(obj);
  66. // 创建表格元素
  67. const table = document.createElement('table');
  68. //表头
  69. table.createCaption().textContent = '驾考宝典';
  70. // 创建表头,并尾部添加新行,将表头参数填入
  71. const tr = table.createTHead().insertRow(-1);
  72. tr.insertCell(0).innerText = 'id';
  73. tr.insertCell(1).innerText = '图片';
  74. tr.insertCell(2).innerText = '问题';
  75. tr.insertCell(3).innerText = '选项1';
  76. tr.insertCell(4).innerText = '选项2';
  77. tr.insertCell(5).innerText = '选项3';
  78. tr.insertCell(6).innerText = '选项4';
  79. tr.insertCell(7).innerText = '答案';
  80. //遍历驾考宝典问题
  81. document.body.appendChild(table);
  82. obj.result.forEach(item => {
  83. // 生成一个新行,并插入到表尾
  84. const url = item.url;
  85. console.log(url);
  86. const row = table.insertRow(-1);
  87. row.insertCell(0).innerText = item.id;
  88. row.insertCell(1).innerHTML = "<img " + "src=" + `'`+ url +`'` + ">";
  89. // 将生成的该行插入到表格元素中
  90. table.appendChild(row);
  91. row.insertCell(2).innerText = item.question;
  92. row.insertCell(3).innerText = item.item1;
  93. row.insertCell(4).innerText = item.item2;
  94. row.insertCell(5).innerText = item.item3;
  95. row.insertCell(6).innerText = item.item4;
  96. row.insertCell(7).innerText = item.answer;
  97. });
  98. // 最后将表格添加到页面中
  99. document.body.appendChild(table);
  100. </script>
  101. </body>
  102. </html>

三.COMPOSER 常用指令

1. composer 是什么

  • php 包依赖管理工具
  • 包: 组件,一组相关的类,接口,trait 的结合体
  • 依赖: A -> B -> C -> D
  • composer 就是用 php 语言开发的

2. 组件放在了哪里

  • github.com, gitee.com
  • 查询平台: https://packagist.org

3. 从哪下载

  • 官网下载:https://getcomposer.org/
  • 中文网: https://www.phpcomposer.com/

4. windows 下载

  • 官网下载: https://getcomposer.org/composer.phar
  • 将 php.exe 所在路径添加到全局 path 变量中
  • 将下载的 composer.phar 复制到 php.exe 所在目录中
  • 创建 composer.bat:@php "%~dp0composer.phar" %*

  • php composer.phar -V

  • 简化成: composer -V
  • 将镜像改为国内阿里云:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

5. 常用指令

  • composer install: 安装 composer.json 中的依赖
  • composer update: 更新依赖
  • composer selfupdate: 更新 composer 版本
  • composer require: 添加依赖到 composer.json 中
  • composer create-project: 安装项目
  • composer config -l -g 查看composer配置
  • composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

6. 自动加载 autoload

  • 文件级: “files”, 需要将加载的文件逐个导入
  • 目录级: “classmap”,类目录的映射
  • 空间级: “psr-4”: 命名空间映射到目录
  • 无论是哪一种,最后都要执行一下”composer dump”,更新 composer.json 中的 autoload 配置项

更多相关文章

  1. 微信群活码生成系统,群活码、客服活码、一套非常棒的免费开源群活
  2. php之请求api数据与composer
  3. 快递公司如何接入快递100?快递100电子面单接口的示例
  4. 快递公司如何接入快递100?快递100的快递查询订阅推送接口示例
  5. 快递公司如何接入快递100?快递100的快递实时查询接口示例
  6. 【PHP扩展知识】URL相关函数和API接口案例以及Composer的安装与
  7. 漫画设计模式:什么是 “职责链模式” ?
  8. C# | 批量将CAD图幅网格外扩生成新图框(附源代码下载)
  9. 熔断原理与实现Golang版

随机推荐

  1. Go语言并发机制图文详解
  2. go语言查看环境信息的方法
  3. golang context用来干吗
  4. 在go modules里使用go get进行包管理的介
  5. Go生成go动态库或静态库的方法
  6. golang channel有什么好处
  7. golang channel是什么
  8. go中的数据结构-字典map详解
  9. Golang Cgo是什么
  10. go中的数据结构-接口interface(详解)