PHP知识杂记

PHP是最好的语言

Posted by tianhaoo on November 1, 2017 本文阅读量

实现一个纯前端的静态登陆界面

先上代码

如果你已经装好了wamp环境,那么你只需要在htdocs文件夹下创建一个名为form1.html的文件,把这些代码写进去就好了。

(我的htdocs文件夹路径为C:\Bitnami\wampstack-7.1.8-0\apache2\htdocs视自己情况而定)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>simpleForm</title>
    </head>
    <body>
        <form>
            用户名:<input type="text" name="name">
            密码:<input type="text" name="password">
            <input type="submit" value="提交">
        </form>
    </body>

</html>

然后在浏览器里键入http://localhost/form1.html (这里的from1.html是因为我上文创建这个文件为form1.html,具体看自己怎么命名的)

接下来是一步一步的解释

先是第一行

<!DOCTYPE html>
  • <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前。
  • <!DOCTYPE> 声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。

(其实要是没有特殊要求,很浏览多器不写也行, 而且还有更复杂的写法)

more

head标签

<head>
    <meta charset="utf-8">
    <title>simpleForm</title>
</head>
  • head 标签用于定义文档的头部,它是所有头部元素的容器。head中的元素可以引用脚本、指示浏览器在哪里找到样式表、提供元信息等等。(虽然你们现在看不懂什么意思)
  • 文档的头部描述了文档的各种属性和信息,包括文档的标题、在 Web 中的位置以及和其他文档的关系等。绝大多数文档头部包含的数据都不会真正作为内容显示给读者。
  • 下面这些标签可用在 head 部分:link, meta, script, style, title

meta标签

<meta charset="utf-8">
  • title定义文档的标题,它是 head 部分中唯一必需的元素。

body标签

<body>
    <form action="" name="" type="" method="">
        名字:<input type="text" name="name">
        性别:<input type="text" name="password">
        <input type="submit" value="提交">
    </form>
</body>
  • body 元素定义文档的主体。
  • body 元素包含文档的所有内容(比如文本、超链接、图像、表格和列表等等。)

input标签

<input type="text" name="name">
<input type="text" name="password">
<input type="submit" value="提交">
  • input 标签用于搜集用户信息。
  • 在input标签里,根据不同的 type 属性值,输入字段拥有很多种形式。常见的几种属性如下
    • text 定义常规文本输入。
    • radio 定义单选按钮输入(选择多个选择之一)
    • checkbox 定义复选框
    • submit 定义提交按钮(提交表单)
    • more

form标签

<form name="" action="" method="" target="" >
    名字:<input type="text" name="name">
    性别:<input type="text" name="password">
    <input type="submit" value="提交">
</form>
  • form 标签用于为用户输入创建 HTML 表单。(由上文提到的submit按钮来提交表单)
  • 表单能够包含 input 元素,比如文本字段、复选框、单选框、提交按钮等等。(如上文所说)
  • 表单还可以包含 menus、textarea、fieldset、legend 和 label 元素。
  • 表单用于向服务器传输数据。
  • 表单有这些常用的属性如下
    • action 规定当提交表单时向何处发送表单数据。
    • method 规定用于发送 form-data 的 HTTP 方法。
    • name 规定表单的名称。
    • target 规定在何处打开 action URL。
    • more

(上面的body标签里面没有定义这些属性,默认是空,具体的值可以在上面的more里看到)

好了到现在为止就完成了一个登陆页面,但是点了提交之后并没有任何反应,提交的数据都没了。那是因为我们没有写后端的操作(action属性),下一篇博客将会是关于form表单的后端操作.

上一篇博客实现了一个前端的登陆页面,提供了填写用户名和密码的地方,

遗憾的是点击提交后所填写的用户名和密码都无处可寻,

这次写一个php文件,拿出用户提交的数据。

这是上次写的前端登陆页面

form1.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>simpleForm</title>
    </head>
    <body>
        <form>
            用户名:<input type="text" name="name">
            密码:<input type="text" name="password">
            <input type="submit" value="提交">
        </form>
    </body>
</html>

首先在同级目录下创建一个form_action.php文件, 在其中加上如下内容

<?php
echo "Here you are! Now you are in form_action.php";
?>

echo, print, var_dump()的用法

在form1.html里面给form标签加上action属性

<form action="form_action.php">

保存后再次点击“提交”,发现屏幕上显示了一段你让它显示的话。

这就说明,action属性是用来指明用户点了提交后,将要执行什么操作

两个超全局变量

上面的例子只是简单的显示了一段话,那么怎么把用户提交的数据提取出来呢?很简单,php有两个超全局变量分别叫$_GET和$_POST,那么又不得不提form的另一个属性method.

上文讲到method是用来规定用于发送 form-data 的 HTTP 方法的属性,可以自己试着将刚才的例子里分别加上method=”post”或者method=”get”,中间别忘了空格。

发现两者的不同在于,get方法的url很长,post方法url不变。就是因为GET是通过URL参数传递到当前脚本的变量数组。POST是通过HTTP POST传递到本当前脚的变量数组。

所以如果使用get方法那么超全局变量就是$_GET,post方法超全局变量就是$_POST,那么我们可以在form_action.php里面写入如下代码提取出用户提交的数据,取决于form的action是何属性,默认是get

// 使用get方法
你好,<?php echo $_GET['name']; ?>。
你的密码是 <?php echo $_GET['password']; ?>。

// 使用post方法
你好,<?php echo $_POST['name']; ?>。
你的密码是 <?php echo $_POST['password']; ?> 。

这样就能做到将前端的数据传到后端。大多数用php写的网站也都是这样获取用户信息的,最多加一些其他的操作,原理都是一样的。

GET vs. POST

  • GET 和 POST 都创建数组(例如,array( key => value, key2 => value2, key3 => value3, …))。此数组包含键/值对,其中的键是表单控件的名称,而值是来自用户的输入数据。
  • GET 和 POST 被视作 $_GET 和 $_POST。它们是超全局变量,这意味着对它们的访问无需考虑作用域 - 无需任何特殊代码,您能够从任何函数、类或文件访问它们。
  • $_GET 是通过 URL 参数传递到当前脚本的变量数组。
  • $_POST 是通过 HTTP POST 传递到当前脚本的变量数组。

何时使用 GET?

  • 通过 GET 方法从表单发送的信息对任何人都是可见的(所有变量名和值都显示在 URL 中)。GET 对所发送信息的数量也有限制。限制在大于 2000 个字符。不过,由于变量显示在 URL 中,把页面添加到书签中也更为方便。
  • GET 可用于发送非敏感的数据。
  • 绝不能使用 GET 来发送密码或其他敏感信息!

何时使用 POST?

  • 通过 POST 方法从表单发送的信息对其他人是不可见的(所有名称/值会被嵌入 HTTP 请求的主体中),并且对所发送信息的数量也无限制。
  • 此外 POST 支持高阶功能,比如在向服务器上传文件时进行 multi-part 二进制输入。
  • 不过,由于变量未显示在 URL 中,也就无法将页面添加到书签。
  • 提示:开发者偏爱 POST 来发送表单数据。

PHP连接Mysql数据库

一个web应用总是少不了数据库

以最简单的mysql为例,了解php中mysql的用法

什么是 MySQL?

  • MySQL 是一种数据库。数据库定义了存储信息的结构。

  • 在数据库(database)中,存在着一些表(table),表中有一些字段(columns)。

如何使用MySQL

  • 如果使用了wamp, 则在×××/mysql/bin/目录下打开命令行,或者可以添加mysql到环境变量,就可以在全局使用MySQL。
  • 登录MySQL

    mysql -u root -p

    输入安装mysql时的密码, 将会出现类似下面的提示

    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 5
    Server version: 5.7.20-0ubuntu0.16.04.1 (Ubuntu)
    
    Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    

    忘记密码

  • 查看所有的数据库

    show databases; # 别忘了分号

    结果

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    4 rows in set (0.00 sec)
    
    mysql>
    
  • 选定一个数据库

    use mysql

    结果

    mysql> use mysql
    Database changed
    
  • 查看所有的表

    show tables;

    结果

    mysql> show tables;
    +---------------------------+
    | Tables_in_mysql           |
    +---------------------------+
    | columns_priv              |
    | db                        |
    | engine_cost               |
    | event                     |
    | func                      |
    | general_log               |
    | gtid_executed             |
    | help_category             |
    | help_keyword              |
    | help_relation             |
    | help_topic                |
    | innodb_index_stats        |
    | innodb_table_stats        |
    | ndb_binlog_index          |
    | plugin                    |
    | proc                      |
    | procs_priv                |
    | proxies_priv              |
    | server_cost               |
    | servers                   |
    | slave_master_info         |
    | slave_relay_log_info      |
    | slave_worker_info         |
    | slow_log                  |
    | tables_priv               |
    | time_zone                 |
    | time_zone_leap_second     |
    | time_zone_name            |
    | time_zone_transition      |
    | time_zone_transition_type |
    | user                      |
    +---------------------------+
    31 rows in set (0.00 sec)
    

    // 这个数据库里面表有点多。。

  • 查看表里面所有的字段

    show columns from help_topic;

    结果

    mysql> show columns from help_topic;
    +------------------+----------------------+------+-----+---------+-------+
    | Field            | Type                 | Null | Key | Default | Extra |
    +------------------+----------------------+------+-----+---------+-------+
    | help_topic_id    | int(10) unsigned     | NO   | PRI | NULL    |       |
    | name             | char(64)             | NO   | UNI | NULL    |       |
    | help_category_id | smallint(5) unsigned | NO   |     | NULL    |       |
    | description      | text                 | NO   |     | NULL    |       |
    | example          | text                 | NO   |     | NULL    |       |
    | url              | text                 | NO   |     | NULL    |       |
    +------------------+----------------------+------+-----+---------+-------+
    6 rows in set (0.00 sec)
    
  • 显示表里面的所有信息

    select * from help_topic;

    这个太长了,结果就不贴了。

    Learn More

    所以数据库语法还是很简单的,但是用起来每次都得输入这么长一堆命令,就太麻烦了,好在我们并不需要经常手动去操作数据库,这就要用到我们的php连接mysql操作了

php 连接mysql

这是我们之前写的例子

form.html ``` <!DOCTYPE html>

my-form
用户名: 密码:
  > form_action.php

你好,<?php echo $_GET[‘name’]; ?>。 你的密码是 <?php echo $_GET[‘password’]; ?>。


##### 现在我们在form_action里面添加操作,把用户输入的用户名密码放到数据库里

1. 首先我们得有个数据库
  - 按照之前的操作在命令行里登录mysql
  - 创建一个名为my-form-db的数据库 `create database my-form-db;`
    ```
    mysql> create database my_form_db;
    Query OK, 1 row affected (0.00 sec)
    ```
  - 切换数据库
    ```
    mysql> use my_form_db;
    Database changed
    ```
  - 创建数据表
    ```
    mysql> create table user_info(
        -> user_id int not null auto_increment,
        -> user_name varchar(100) not null,
        -> user_passwd varchar(100) not null,
        -> sub_time date,
        -> primary key(user_id)
        -> )engine=innodb default charset=utf8;
    Query OK, 0 rows affected (0.01 sec)
    // mysql虽然不区分大小写,但习惯上将关键字大写,别学我,小写不是个好习惯。
    ```
  - 你可以查看你刚刚创建的数据表有哪些字段
    ```
    mysql> show tables;
    +----------------------+
    | Tables_in_my_form_db |
    +----------------------+
    | user_info            |
    +----------------------+
    1 row in set (0.01 sec)

    mysql> show columns from user_info;
    +-------------+--------------+------+-----+---------+----------------+
    | Field       | Type         | Null | Key | Default | Extra          |
    +-------------+--------------+------+-----+---------+----------------+
    | user_id     | int(11)      | NO   | PRI | NULL    | auto_increment |
    | user_name   | varchar(100) | NO   |     | NULL    |                |
    | user_passwd | varchar(100) | NO   |     | NULL    |                |
    | sub_time    | date         | YES  |     | NULL    |                |
    +-------------+--------------+------+-----+---------+----------------+
    4 rows in set (0.01 sec)
    ```
  - [更多关于创建数据库的操作](http://www.runoob.com/mysql/mysql-create-tables.html)

2. 在form_action里面编写代码,插入用户的数据
  - 首先我们得连接已经创建的数据库,就要用到[mysqli_connect()](http://www.runoob.com/php/func-mysqli-connect.html)这个函数,别忘了[开启mysqli扩展](https://www.cnblogs.com/zhdevelop/archive/2013/03/17/2964226.html),本例用法如下
    ```php
    <?php
    $db_host='127.0.0.1';
    $db_user='root';
    $db_psw='your_password';
    $db_name='my_form_db';

    $conn = mysqli_connect($db_host,$db_user,$db_psw, $db_name) or die('数据库连接失败');

    if(!$conn) {
        echo "连接失败<br>";
    }
    else{
        echo "连接成功<br>";
    }
    ```

  - 其次我们要插入用户名和密码以及时间
    ```php
    <?php
    $db_host='127.0.0.1';
    $db_user='root';
    $db_psw='your_password';
    $db_name='my_form_db';
    $db_charset='utf8';

    $sql = "insert into user_info (user_name, user_passwd, sub_time) values ('$my_name', '$my_password', now())";

    $conn = mysqli_connect($db_host,$db_user,$db_psw, $db_name) or die('数据库连接失败');

    if(!$conn) {
        echo "连接失败<br>";
    }
    else{
        echo "连接成功<br>";
    }

    $conn->set_charset('utf8'); //设置查询结果编码

    if ($conn->query($sql) === TRUE) {
        echo "新记录插入成功";
    } else {
        echo "Error:" . $sql . "<br>" . $conn->error;
    }

    $conn->close();
    ```

    - 到目前为止就完成了php与mysql之间的通信,我们可以去数据库里面看看我们都插入了什么数据。
    ```
    mysql> select * from user_info;
    +---------+-----------------+-----------------------+------------+
    | user_id | user_name       | user_passwd           | sub_time   |
    +---------+-----------------+-----------------------+------------+
    |       1 | Jack            | Ross                  | 2018-01-20 |
    |       2 | my_name         | my_password           | 2018-01-20 |
    |       3 | 我和你          | 心连心                | 2018-01-20 |
    |       4 | 123456          | adsfl                 | 2018-01-20 |
    |       5 | 跟着我左手      | 右手一个慢动作        | 2018-01-20 |
    +---------+-----------------+-----------------------+------------+
    5 rows in set (0.00 sec)

    mysql>
    ```

    - 在页面里面读取并且显示数据库里的内容
    ```php
    <?php

    $my_name = $_POST['name'];
    $my_password = $_POST['password'];

    echo '你好'.$my_name."<br>".'你的密码是'.$my_password."<br>";

    // 定义一些变量
    $db_host='127.0.0.1';
    $db_user='root';
    $db_psw='your_password';
    $db_name='my_form_db';
    $db_charset='utf8';

    $sql = "insert into user_info (user_name, user_passwd, sub_time) values ('$my_name', '$my_password', now())";
    $sql2 = "select * from user_info";


    // 连接数据库
    $conn = mysqli_connect($db_host,$db_user,$db_psw, $db_name) or die('数据库连接失败');
    $conn->set_charset('utf8'); //设置查询结果编码

    if(!$conn) {
        echo "连接失败<br>";
    }
    else{
        echo "连接成功<br>";
    }


    // 插入数据
    if ($conn->query($sql) === TRUE) {
        echo "新记录插入成功<br>";
    } else {
        echo "Error:" . $sql . "<br>" . $conn->error;
    }

    // 查询数据
    $result = $conn->query($sql2);

    if ($result->num_rows > 0) {
        echo "查询结果如下<br>";
        while($row = $result->fetch_assoc()) {
            echo "id: " . $row["user_id"]. "----名字:" . $row["user_name"]. "----密码:" . $row["user_passwd"]. "----提交时间:". $row["sub_time"] . "<br>";
        }
    } else {
        echo "数据库里没有记录<br>";
    }

    $conn->close();
    ```



## PHP的socket编程


### GET方法的socket通信

#### client.php
<!-- more -->
```php
<?php

    // 创建连接
    $fp = fsockopen('localhost', 80, $errno, $errstr, 80);

    // 检测
    if(!$fp) {
        echo $errstr; die;
    }

    // 拼接http请求报文
    $http = '';

    // 请求报文包括三个部分 请求行 请求头 请求体
    $http .= "GET /http/server.php HTTP/1.1\r\n"; // 请求头包括三个部分 请求方式 请求脚本的绝对路径 协议的版本号

    // 请求头信息
    $http .= "HOST: localhost\r\n";
    $http .= "Connection: close\r\n\r\n"; //创建完连接后立刻断开,还有一种是keep-alive

    // 请求体 无


    // 发送请求
    fwrite($fp, $http);

    // 获取结果
    $res = '';
    while(!feof($fp)) {
        $res .= fgets($fp);
    }

    echo $res;

server.php

<?php

    echo "Hello world!";

响应内容

// 响应行
HTTP/1.1 200 OK  

// 响应头
Date: Thu, 25 Jan 2018 05:58:21 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/7.1.8
Content-Length: 12
Connection: close
Content-Type: text/html; charset=UTF-8

// 响应体
Hello world!

POST方法的socket通信

post.php

<?php

    // 创建连接
    $fp = fsockopen('localhost', 80, $errno, $errstr, 10);

    // 判断
    if(!$fp) {
        echo $errstr; die;
    }

    $http = '';

    // 请求行
    $http .= "POST /http/server.php HTTP/1.1\r\n";

    // 请求头
    $http .= "Host: localhost\r\n";
    $http .= "Connection: close\r\n";
    $http .= "Cookie: username=admin;uid=200\r\n";
    $http .= "user-agent: chrome-firefox\r\n";
    $http .= "Content-type: application/x-www-form-urlencoded\r\n";
    $http .= "Content-length: 39\r\n\r\n";

    // 请求行和请求体之间必须加两个\r\n

    // 请求体
    $http .= "email=tianhaoo@gmail.com&username=admin\r\n";

    // 发送
    fwrite($fp, $http);

    $res = '';
    // 获取结果
    while(!feof($fp)) {
        $res .= fgets($fp);
    }

    echo $res;



server.php

<?php

    echo "Hello world!1234";

    // var_dump($_GET);
    // var_dump($_POST);

    // 打印cookie
     var_dump($_COOKIE);


    // var_dump($GLOBALS);
     // var_dump($_SERVER);

API请求天气

weather.php

<?php
/**
 * Created by PhpStorm.
 * User: Tianhaoo
 * Date: 2018/1/26
 * Time: 6:42
 */
    // 72ae96aaf8cf7af9d7bc1267c938b146
    $fp = fsockopen('way.jd.com', 80,$errno, $errstr, 10);

    if(!$fp) {
        echo $errstr; die;
    }

    $http = '';

    // 请求行
    $http .= "GET /he/freeweather?city=beijing&appkey=72ae96aaf8cf7af9d7bc1267c938b146 HTTP/1.1\r\n";

    // 请求头
    $http .= "Host: way.jd.com\r\n";
    $http .= "Connection: close\r\n";
    $http .= "appkey: 72ae96aaf8cf7af9d7bc1267c938b146\r\n\r\n";

    //发送
    fwrite($fp, $http);

    // 获取结果
    $res = '';

    while(!feof($fp)) {
        $res .= fgets($fp);
    }

    echo $res;

请求结果

HTTP/1.1 200 OK
Server: jfe
Date: Fri, 26 Jan 2018 07:08:26 GMT
Content-Type: application/json;charset=utf-8
Content-Length: 5420
Connection: close
Expires: Fri, 26 Jan 2018 07:08:25 GMT
Cache-Control: max-age=0

{
  "code": "10000",
  "charge": false,
  "msg": "查询成功",
  "result": {
    "HeWeather5": [
      {
        "aqi": {
          "city": {
            "aqi": "46",
            "qlty": "优",
            "pm25": "32",
            "pm10": "44",
            "no2": "42",
            "so2": "10",
            "co": "1",
            "o3": "42"
          }
        },
        "basic": {
          "city": "北京",
          "cnty": "中国",
          "id": "CN101010100",
          "lat": "39.90498734",
          "lon": "116.4052887",
          "update": {
            "loc": "2018-01-26 14:15",
            "utc": "2018-01-26 06:15"
          }
        },
        "daily_forecast": [
          {
            "astro": {
              "mr": "12:33",
              "ms": "01:33",
              "sr": "07:27",
              "ss": "17:27"
            },
            "cond": {
              "code_d": "100",
              "code_n": "101",
              "txt_d": "晴",
              "txt_n": "多云"
            },
            "date": "2018-01-26",
            "hum": "21",
            "pcpn": "0.0",
            "pop": "0",
            "pres": "1038",
            "tmp": {
              "max": "-4",
              "min": "-10"
            },
            "uv": "2",
            "vis": "20",
            "wind": {
              "deg": "189",
              "dir": "南风",
              "sc": "微风",
              "spd": "7"
            }
          },
          {
            "astro": {
              "mr": "13:16",
              "ms": "02:41",
              "sr": "07:26",
              "ss": "17:28"
            },
            "cond": {
              "code_d": "101",
              "code_n": "101",
              "txt_d": "多云",
              "txt_n": "多云"
            },
            "date": "2018-01-27",
            "hum": "37",
            "pcpn": "0.0",
            "pop": "0",
            "pres": "1032",
            "tmp": {
              "max": "-1",
              "min": "-9"
            },
            "uv": "2",
            "vis": "20",
            "wind": {
              "deg": "184",
              "dir": "南风",
              "sc": "微风",
              "spd": "6"
            }
          },
          {
            "astro": {
              "mr": "14:05",
              "ms": "03:50",
              "sr": "07:25",
              "ss": "17:29"
            },
            "cond": {
              "code_d": "100",
              "code_n": "100",
              "txt_d": "晴",
              "txt_n": "晴"
            },
            "date": "2018-01-28",
            "hum": "16",
            "pcpn": "0.0",
            "pop": "0",
            "pres": "1035",
            "tmp": {
              "max": "0",
              "min": "-8"
            },
            "uv": "2",
            "vis": "20",
            "wind": {
              "deg": "5",
              "dir": "北风",
              "sc": "微风",
              "spd": "8"
            }
          },
          {
            "astro": {
              "mr": "15:03",
              "ms": "04:57",
              "sr": "07:24",
              "ss": "17:31"
            },
            "cond": {
              "code_d": "100",
              "code_n": "100",
              "txt_d": "晴",
              "txt_n": "晴"
            },
            "date": "2018-01-29",
            "hum": "21",
            "pcpn": "0.0",
            "pop": "0",
            "pres": "1032",
            "tmp": {
              "max": "1",
              "min": "-8"
            },
            "uv": "2",
            "vis": "20",
            "wind": {
              "deg": "228",
              "dir": "西南风",
              "sc": "微风",
              "spd": "8"
            }
          },
          {
            "astro": {
              "mr": "16:07",
              "ms": "06:00",
              "sr": "07:24",
              "ss": "17:32"
            },
            "cond": {
              "code_d": "101",
              "code_n": "101",
              "txt_d": "多云",
              "txt_n": "多云"
            },
            "date": "2018-01-30",
            "hum": "20",
            "pcpn": "0.0",
            "pop": "0",
            "pres": "1029",
            "tmp": {
              "max": "4",
              "min": "-5"
            },
            "uv": "1",
            "vis": "20",
            "wind": {
              "deg": "247",
              "dir": "西南风",
              "sc": "微风",
              "spd": "4"
            }
          },
          {
            "astro": {
              "mr": "17:18",
              "ms": "06:57",
              "sr": "07:23",
              "ss": "17:33"
            },
            "cond": {
              "code_d": "101",
              "code_n": "101",
              "txt_d": "多云",
              "txt_n": "多云"
            },
            "date": "2018-01-31",
            "hum": "19",
            "pcpn": "0.0",
            "pop": "0",
            "pres": "1029",
            "tmp": {
              "max": "4",
              "min": "-5"
            },
            "uv": "2",
            "vis": "20",
            "wind": {
              "deg": "281",
              "dir": "西北风",
              "sc": "微风",
              "spd": "8"
            }
          },
          {
            "astro": {
              "mr": "18:29",
              "ms": "07:46",
              "sr": "07:22",
              "ss": "17:34"
            },
            "cond": {
              "code_d": "101",
              "code_n": "101",
              "txt_d": "多云",
              "txt_n": "多云"
            },
            "date": "2018-02-01",
            "hum": "21",
            "pcpn": "0.0",
            "pop": "0",
            "pres": "1030",
            "tmp": {
              "max": "2",
              "min": "-8"
            },
            "uv": "2",
            "vis": "20",
            "wind": {
              "deg": "1",
              "dir": "北风",
              "sc": "3-4",
              "spd": "14"
            }
          }
        ],
        "hourly_forecast": [
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-26 16:00",
            "hum": "19",
            "pop": "0",
            "pres": "1035",
            "tmp": "-3",
            "wind": {
              "deg": "154",
              "dir": "东南风",
              "sc": "微风",
              "spd": "5"
            }
          },
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-26 19:00",
            "hum": "22",
            "pop": "0",
            "pres": "1034",
            "tmp": "-3",
            "wind": {
              "deg": "118",
              "dir": "东南风",
              "sc": "微风",
              "spd": "3"
            }
          },
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-26 22:00",
            "hum": "24",
            "pop": "0",
            "pres": "1034",
            "tmp": "-5",
            "wind": {
              "deg": "88",
              "dir": "东风",
              "sc": "微风",
              "spd": "3"
            }
          },
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-27 01:00",
            "hum": "33",
            "pop": "0",
            "pres": "1037",
            "tmp": "-5",
            "wind": {
              "deg": "63",
              "dir": "东北风",
              "sc": "微风",
              "spd": "3"
            }
          },
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-27 04:00",
            "hum": "29",
            "pop": "0",
            "pres": "1037",
            "tmp": "-6",
            "wind": {
              "deg": "26",
              "dir": "东北风",
              "sc": "微风",
              "spd": "4"
            }
          },
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-27 07:00",
            "hum": "30",
            "pop": "0",
            "pres": "1036",
            "tmp": "-8",
            "wind": {
              "deg": "21",
              "dir": "东北风",
              "sc": "微风",
              "spd": "4"
            }
          },
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-27 10:00",
            "hum": "19",
            "pop": "0",
            "pres": "1036",
            "tmp": "-7",
            "wind": {
              "deg": "15",
              "dir": "东北风",
              "sc": "微风",
              "spd": "4"
            }
          },
          {
            "cond": {
              "code": "103",
              "txt": "晴间多云"
            },
            "date": "2018-01-27 13:00",
            "hum": "14",
            "pop": "0",
            "pres": "1033",
            "tmp": "-2",
            "wind": {
              "deg": "237",
              "dir": "西南风",
              "sc": "微风",
              "spd": "6"
            }
          }
        ],
        "now": {
          "cond": {
            "code": "100",
            "txt": "晴"
          },
          "fl": "-9",
          "hum": "26",
          "pcpn": "0.0",
          "pres": "1037",
          "tmp": "-5",
          "vis": "10",
          "wind": {
            "deg": "267",
            "dir": "西风",
            "sc": "微风",
            "spd": "7"
          }
        },
        "status": "ok",
        "suggestion": {
          "air": {
            "brf": "中",
            "txt": "气象条件对空气污染物稀释、扩散和清除无明显影响,易感人群应适当减少室外活动时间。"
          },
          "comf": {
            "brf": "较不舒适",
            "txt": "白天天气晴好,但仍会使您感觉偏冷,不很舒适,请注意适时添加衣物,以防感冒。"
          },
          "cw": {
            "brf": "较适宜",
            "txt": "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。"
          },
          "drsg": {
            "brf": "寒冷",
            "txt": "天气寒冷,建议着厚羽绒服、毛皮大衣加厚毛衣等隆冬服装。年老体弱者尤其要注意保暖防冻。"
          },
          "flu": {
            "brf": "较易发",
            "txt": "天气较凉,较易发生感冒,请适当增加衣服。体质较弱的朋友尤其应该注意防护。"
          },
          "sport": {
            "brf": "较不宜",
            "txt": "天气较好,但考虑天气寒冷,推荐您进行室内运动,户外运动时请注意保暖并做好准备活动。"
          },
          "trav": {
            "brf": "较适宜",
            "txt": "天气较好,同时又有微风伴您一路同行。稍冷,较适宜旅游,您仍可陶醉于大自然的美丽风光中。"
          },
          "uv": {
            "brf": "最弱",
            "txt": "属弱紫外线辐射天气,无需特别防护。若长期在户外,建议涂擦SPF在8-12之间的防晒护肤品。"
          }
        }
      }
    ]
  }
}

好玩!