php7实践指南第20章 基于前端架构打造服务端

前端技术的发展非常迅速,特别是近年来各种框架如雨后春笋般不断出现,这些前端框架在数据绑定、模板渲染等方面做得非常优秀。专职的前端架构师能够应用好这些前端框架,基于PHP的服务端就可以专注于数据的后端处理,提供好接口服务,完成数据库存储等方面的工作。

20.1 构建一个API的世界

随着移动互联网的发展、多终端的出现,为了降低服务端的工作量和以后的维护量,我们希望开发一套可适用于多个终端的接口。面向接口编程要求我们将定义和实现分离,尽可能编写粒度更细的接口,降低各个接口之间的依赖度,这些接口通过一定的组合能够对外提供一套系统服务。

随着技术的发展,网络上的数据传输都会以API的形式展现,json和XML是最常用的两种数据传输格式。传统的网站,以ThinkPHP为例搭建的网站,都是MVC分离,通过一定的程序将view层面拿出来,由前端开发人员写了静态页面,交由后台开发者整合成一个网站。这种模式在只需要一个PC站的情况下是一个很不错的选择,结构清晰,一般也不会出现什么问题。

但是问题来了,当你需要的不仅仅只是一个PC站,还需要有更多的如微信端网站、App之类的时候,此时如果还采用原来的架构,那么你就需要至少写3套程序分别适应3个终端。很多情况下,你的App网站和手机站的功能实现和逻辑是相通的,这样写出来的3套程序就会带来很大的冗余,有很多重复的逻辑代码在里面。当你变动需求的时候,需要3套程序都跟着变动,也不利于后期的维护升级。

这时我们应该采用一种全新的架构,以另外一种思路去建设这样3个终端。应该写一个统一的Server端程序,你可以使用Java、Python或着PHP写,它的功能就是实现对数据库的操作,对数据库进行增、删、改、查,客户端(这里我们把APP网站和手机站点统称为客户端,当然也可能会有其他的终端)通过传递一定的参数调用不同的接口,完成交互。Server端程序可以使用流行的restful规范,可以抽象出一个基类,App和PC需要的数据一样的话可以使用同一接口。需要用到不同的接口时,先在Server端封装一个基类,然后分别继承这个基类写两个接口,分别适用于App和PC。总体来说,要实现高内聚、低耦合,即业务逻辑在方法内部实现,对外提供完好的客户端需要的数据,各个方法之间依赖度低,有利于维护整合。能抽象出来的就单独拿出来,能封装的就封装,在开发中遵循don't repeat yourself的法则。

这时对于网站前端来说,可能要求就不只是简单地写HTML和CSS了,更多的需要用到Ajax进行数据的请求。这时前端也就需要考虑应该用什么来写了,你可以使用流行的AnjularJS,这是一个非常流行并被前端开发人员强烈推荐的前端框架,遵循AMD规范,具体内容读者可以到官方网站https://angularjs.org/查看有关资料。

20.1.2 API接口签名验证

客户端在向服务端请求数据的时候,服务端需要对请求进行验证,确保请求来源是合法的,否则会导致网站数据泄漏。服务端和客户端实现签名验证的方式并不是固定的,可由服务端和客户端开发人员共同协商制定,只要保证服务端能够正确地验证请求是来自特定客户端即可。

一般是客户端和服务端使用相同的签名实现算法,客户端在向服务端发起请求时携带参与签名计算的参数和计算后的签名字符串(一般称作signature),服务端接收到这些参数后,按照相同的算法加密这些参数,生成自己的签名字符串,将这个signature和接收到的signature进行比较,若相等则验证通过。

在这里我们规定一种签名算法,客户端发起请求时需携带signature(加密签名)、timestamp(时间戳)、randstr(随机字符串)、data(消息内容,多个请求参数间用&连接,如uid=1111&name=chenxiaolong;)4个参数。加密/校验流程如下:

● 将randstr、timestamp、data组成数组。

● 对数组进行字典排序。

● 循环数组的值组成一个字符串,对字符串进行sha1加密,生成signature签名。

一个访问接口URL的组成示例如下:

http://php.jingpan.io/php_practice_guide/ch20phpapi/apisign.php?timestamp=1479651758&randstr=123456&uid=1111&name=chenxiaolong&sign=3e7d9f410dad146f0722425946626dbc3f2f39f3

其中,sign参数由客户端根据上面的加密流程生成。服务端的解密流程如下:

(1)将接收到的randstr、timestamp、data(在本例中为uid=1111&name=chenxiaolong)组成数组。

(2)对数组进行字典排序。

(3)循环数组的值组成一个字符串,对字符串进行sha1加密,生成signature签名。将这个signature和接收的参数sign的值进行比较,若相等则验证通过。

服务端验证代码如下:

<?php
$arr=array(
    'uid'=>$_GET['uid'],
    'name'=>$_GET['name'],
    'randstr'=>$_GET['randstr'],
    'timestamp'=>$_GET['timestamp']);

    foreach($arr as $k=>$v){
        $str.=$v;
    }

   // echo $str;
    $sig=$_GET['sign'];
    $sign=sha1($str);

    if($sign==$sig){
        echo  '签名认证通过';
    }else{
        echo  '签名未认证通过';
    }

 

_________________简单php api开发示例

userinfo.php代码如下

<?php
$id = $_POST["user_id"];
if($id != 10086){
    echo ‘参数错误,使用post方法传入user_id参数’;
    exit;
}

$userinfo = array(
    'username'=>'jason',
    'password'=>'123456',
);

$result = array(
    'code'=>'0',
    'message'=>'成功',
    'data'=>$userinfo,
);
echo json_encode($result);

postman调试信息如下:

20.2 传输消息的加解密

互联网是一个开放的空间,我们的信息在网络上传播可能会被劫持和篡改,确保信息的安全性就要对传输的信息进行加密。详细的加密有3种形式,即单向散列加密、对称加密和非对称加密,开发者在编程中可根据需要采取加密方式。

20.2.1 单向散列加密

单向加密是对不同输入长度的信息进行散列计算,得到固定长度的散列计算值。输入信息的任何微小变化都会导致散列的很大不同,并且这种计算是不可逆的,即无法根据散列值获得明文信息。这种单向散列加密可用于用户密码的保存,即不将用户输入的密码直接保存到数据库,而是对密码进行单向散列加密,将密文存入数据库,用户登录时进行密码验证,同样对输入密码进行散列加密与数据库中密码的密文进行对比,若一致则验证成功。

虽然不能通过算法从散列密文解出明文,但是由于人们设置的密码具有一定的模式(比如使用生日或名字作为密码),因此通过彩虹表(密码和对应的密文关系表)等手段都可以进行猜测式的破解。为了增加单向散列被破解的难度,还可以给散列算法加盐值(salt), salt相当于加密时的密钥,增加破解时的难度。常用的单向散列算法有MD5、SHA等。

20.2.2 对称加密

对称加密是指加密和解密使用的是同一个密钥。对称加密类似接口签名验证,将明文和密钥按照一定的算法进行加密,同样使用密钥和一定的算法对密文进行解密获得明文。PHP中提供了一个MCRYPT扩展,可用于对称加密。

在讲解使用MCRYPT加解密前需要明确以下几个概念。

●算法名称:MCRYPT扩展所支持的密码算法,详细列表可参见mcrypt.c文件。mcrypt支持的算法见文末。

●算法模式:MCRYPT_MODE_modename常量中的一个,或"ecb"、"cbc"、"cfb"、"ofb"、"nofb"和 "stream"字符串中的一个。

● 算法模块:使用mcrypt_module_open()打开的指定算法和模式对应的模块,是一个资源类型。

● 初始向量:加密时需要用到的一个参数,使用mcrypt_create_iv()从随机源创建。

● 初始向量大小:由mcrypt_get_iv_size()返回的指定算法/模式组合的初始向量大小。mcrypt_create_iv()根据初始向量大小创建初始向量。

mcrypt加密需要以下几个步骤。[插图]使用mcrypt_module_open()打开指定算法和模式的对应模块。

  1. mcrypt_get_iv_size()获得指定算法和模式的初始向量长度,或mcrypt_enc_get_iv_size($td)获取打开模块的初始向量长度。
  2. 根据初始向量长度创建初始向量mcrypt_create_iv()。
  3. 初始化加密所需的缓冲区mcrypt_generic_init()。
  4. 加密数据mcrypt_generic()。
  5. 结束加密,执行清理工作mcrypt_generic_deinit()。

mcrypt解密需要以下几个步骤。

  1. 初始化解密模块mcrypt_generic_init()。
  2. 解密数据mcrypt_decrypt()。
  3. 结束解密,执行清理工作mcrypt_generic_deinit()。
  4. 关闭开始时打开的模块mcrypt_module_close。

下面的代码示例说明加解密的过程。

<?php
//使用系统默认异常错误处理机制
ini_set('display_errors',1);            //错误信息
ini_set('display_startup_errors',1);    //php启动错误信息
error_reporting(-1);                    //打印出所有的 错误信息
ini_set('error_log', dirname(__FILE__) . '/error_log.txt'); //将出错信息输出到一个文本文件

class McryptModel{
    protected $td='';
    protected $iv='';
    protected $key='';
    private static $instance = NULL;

    private function __construct($cipher,$mode,$key)
    {
        $this->ciphper=$cipher;
        $this->mode=$mode;
        $this->key=$key;
    }

    //算法实例
    public static function getInstance($ciphpe=MCRYPT_RIJNDAEL_128,$mode=MCRYPT_MODE_CBC,$key='H5g0s1ZshKZ6WikN'){
        if(self::$instance==NULL){
            self::$instance = new self($ciphpe,$mode,$key);
        }
        return self::$instance;
    }

    //加密算法
    function encrypt($str){
        $td=mcrypt_module_open($this->ciphper,'',$this->mode,''); //打开算法模块
        $this->td=$td;

        $iv_size=mcrypt_enc_get_iv_size($td);//获取向量磊大大小
        $iv=mcrypt_create_iv($iv_size,MCRYPT_RAND);
        $this->iv=$iv;

        $num=mcrypt_generic_init($td,$this->key,$iv);//初始华加密空间

        $encypt=mcrypt_generic($td,$str);//执行加密
        mcrypt_generic_deinit($td);//结束加密,执行清理工作
        return base64_encode($encypt);//base64编码成字符串适合数据传输
    }

    //解密算法
    function decyrpt($str){
        $str=base64_decode($str);
        $td=$this->td;
        mcrypt_generic_init($td,$this->key,$this->iv);
        $decrypt=mdecrypt_generic($td,$str);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);//关闭算法模块
        return $decrypt;
    }
}

$m=McryptModel::getInstance();
//var_dump($m);
echo $s=$m->encrypt('hello world 中国人!');
echo "</br>";
echo $m->decyrpt($s);

程序输出:

8d0/DJ2ZiFy3MF/gpZiOWHvJ59Hcdy3mO3P1EyLIBTA=
hello world 中国人!

mcrypt加解密属于对称加密,算法是公开的,安全性来自对秘钥的保密。用户可选择不同的算法名称和算法模式。常用的算法是MCRYPT_RIJNDAEL_128、MCRYPT_DES、rijndael-256等,常用的模式是cbc、ecb。

20.2.3 非对称加密

与对称加密不同的是,非对称加密和解密使用的是不同的密钥,其中一个对外公开作为公钥,另一个只有所有者拥有,称为私钥。用私钥加密的信息只有公钥才能解开,或者反之用公钥加密的信息只有私钥才能解开。常用的非对称加密有RSA算法,RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。PHP中提供基于RSA算法的openssl扩展可实现对数据的非对称加密。

在RSA加解密之前,需要先生成一对公私钥,可使用Linux自带的RSA密钥生成工具openssl获取一对公私钥,也可使用PHP openssl扩展函数生成一对公私钥。使用Linux生成一对公私钥执行以下命令即可:

[root@localhost ~]#openssl genrsa -out rsa_private_key.pem 1024
[root@localhost ~]# openssl  pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out pkcs8_private_key.pem
[root@localhost ~]# openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

 第一条命令生成原始RSA私钥文件rsa_private_key.pem,第二条命令将原始RSA私钥转换为pkcs8格式,第三条生成RSA公钥rsa_public_key.pem。

从上面看出通过私钥能生成对应的公钥,因此我们将私钥private_key.pem用在服务器端,公钥发放给android ios桌面程序等客户端。

使用PHP生成公私钥的代码如下:

.

<?php
$config = array(
    "digest_alg" => "sha512",
    "private_key_bits" => 2048,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
    "config"=>"c:/apache/conf/openssl.cnf",
);

// Create the private and public key
$res = openssl_pkey_new($config);

if(!$res) {
    $res = openssl_pkey_new($config);
}

//var_dump($config);

// Extract the private key from $res to $privKey
openssl_pkey_export($res, $privKey,null,$config);

// Extract the public key from $res to $pubKey
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];

$data = 'hello';

// Encrypt the data to $encrypted using the private key
openssl_private_encrypt($data, $encrypted, $privKey);

echo "密文:<br/>";
echo base64_encode($encrypted);

// Decrypt the data using the public key and store the results in $decrypted
openssl_public_decrypt($encrypted, $decrypted, $pubKey);

echo "明文:".$decrypted;

程序输出

密文:
aXMAFxd/OT/BpZe8CgZWMJWmFzMM1Hvrh23YzJrcU9O7nntashO3FvDjmaH2FVC1hwc8UB5jTxy/Z7AcYY+ytb8T+HhT95Q9/1gs4xtvF3wvRAXkilGpK6I1Qcf4ddo6FHh1+O9NKchq6dyDe+mHAnJS/ZeyPWA6nq/CZ+NNBHqe4kwQLkiWUsTByc12rAsc3aaNZPFlRnoHzt2TpnvysyzhXk5jFl6YOQURmMfmTDIQXkI8XxgKBxC4Gv+2kHnGcpvU6tW4EhB30pVscIhzERkciEZ3ckHjTDO1u2zF5DtVCkujU6djK2yyCb2y2II5GbfgByyYLcQw7Le1Ve0pmw==
明文:hello

https://www.cnblogs.com/andydao/p/10365031.html

使用非对称加解密的示例代码如下:

<?php
$private_key_path='rsa_private_key.pem';
$public_key_path='rsa_public_key.pem';
$private_key=file_get_contents($private_key_path);
$public_key=file_get_contents($public_key_path);

//这个函数可以用来判断私钥是否可用,可用返回资源id(Resorece id),不可用返回false
$pi_key=openssl_pkey_get_private($private_key);
///这个函数可用来判断公钥是否是可用的,同上
$pu_key=openssl_pkey_get_public($public_key);
$data="hello";//原如数据
$encrypted="";
$decrypted="";

//var_dump($pu_key);

//私钥加密,也可使用openssl_public_encrypt公钥加密,然后使用openssl_private_decrypt解密,加密后数据在$encrypted
openssl_private_encrypt($data,$encrypted,$pi_key);
//加密后的内容通常含有特殊字符,需要编码转换下,在网络间骑过URL传输时需要注意base64编码是否是URL安全的
$encrypted=base64_encode($encrypted);
//私钥加密的内容通过公钥可解密出来,公钥加密的可私钥解密,不能混淆
openssl_public_decrypt(base64_decode($encrypted),$decrypted,$pu_key);
echo $decrypted;//hello

非对称加密的缺点是加密和解密花费时间长、速度慢,只适合对少量数据进行加密。如果既想有很快的加密速度又想保证数据比对称加密更加安全,可使用混合加密,即对数据进行对称加密、对密钥做非对称加密,因为一般秘钥的长度会小于数据的长度。解密的时候先用非对称加密得到密钥,再用密钥解开密文得到明文。

RSA是目前最有影响力的公钥加密算法,能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。

今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的,但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战。

20.3 使用Ajax进行交互

把网页看作客户端,服务端以提供接口的形式向客户端提供数据的增、删、改、查服务。在网页开发中,经常使用Ajax技术实现客户端和服务端的数据交互。

20.3.1 Ajax的介绍

AJAX是一种在无须重新加载整个网页的情况下能够更新部分网页的技术。AJAX通过在后台与服务器进行少量数据交换可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下对网页的某部分进行更新。现代浏览器都内置了可以创建Ajax的对象XMLHttpRequest(Internet Explorer(IE 5和IE 6)使用ActiveX对象),这样使得我们可以很方便地创建一个Ajax对象,通过浏览器发起请求来与服务端交互。

你可以使用new XMLHttpRequest()创建一个对象,如果是老版本的InternetExplorer(IE 5和IE 6)使用ActiveX对象(new ActiveXObject)即可。示例如下:

 var xmlhttp;
            if(window.XMLHttpRequest)
            {
                //IE7+、Firefox、Chrome、Opera,Safari浏览器执行代码
                xmlhttp=new XMLHttpRequest();
            }
            else
            {
                //IE6、IE5浏览器执行代码
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }

创建完毕,可使用XMLHttpRequest对象的open()和send()方法向服务器发送请求。示例如下:

 xmlhttp.open("GET","hello.txt",false);
            xmlhttp.send();

open()函数的标准语法是open(method, url, async),其规定了请求的类型method(GET或POST方法)、URL和是否异步处理(true异步,false同步)。send()包含一个参数,仅用于使用POST方法向服务端发送数据。使用POST可向服务器发送较大量的数据,并且POST方式比GET更稳定可靠,但GET方式比POST简单快捷。开发者可根据使用场景选择请求类型。

Ajax指的是异步JavaScript和XML(Asynchronous JavaScript and XML)。

XMLHttpRequest对象如果要用于Ajax,那么其open()方法的async参数就必须设置为true。对于Web开发人员来说,发送异步请求是一个巨大的进步。很多在服务器执行的任务都相当费时。Ajax出现之前,这可能会引起应用程序挂起或停止。通过Ajax、JavaScript无须等待服务器的响应,而是等待服务器响应时执行其他脚本,当响应就绪后对响应再进行处理。当使用async=true后,可以规定在响应结束后执行onreadystatechange事件中的函数。responseText存储从服务端取到的数据,如下面的例子所示:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        function loadXMLDoc(){
            var xmlhttp;
            if(window.XMLHttpRequest)
            {
                //IE7+、Firefox、Chrome、Opera,Safari浏览器执行代码
                xmlhttp=new XMLHttpRequest();
            }
            else
            {
                //IE6、IE5浏览器执行代码
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function () {
                if (xmlhttp.readyState==4 && xmlhttp.status==200)
                {
                    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
                }
            }
            xmlhttp.open("GET","hello.txt",true);
            xmlhttp.send();
        }
    </script>
</head>
<body>
<div id="myDiv"><h2>使用AJAX修改该文本内容</h2>
    <button type="button" onclick="loadXMLDoc()">修改内容</button>
</div>
</body>
</html>

当单击按钮修改内容时便会通过Ajax发起请求取到hello.txt里的内容在页面显示。

当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当readyState改变时就会触发onreadystatechange事件,用户可自定义这个事件的回调函数。readyState存有XMLHttpRequest从0到4发生变化的状态。0表示请求未初始化,1表示服务器连接已经建立,2表示请求已经接收,3代表请求正在处理中,4表示请求已完成。status表示响应完成(readState为4)时此次响应的结果状态,200表示请求成功,404表示请求失败。将上面例子的代码更改为下面这样:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        function loadXMLDoc(){
            var xmlhttp;
            if(window.XMLHttpRequest)
            {
                //IE7+、Firefox、Chrome、Opera,Safari浏览器执行代码
                xmlhttp=new XMLHttpRequest();
            }
            else
            {
                //IE6、IE5浏览器执行代码
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function () {
                if(xmlhttp.readyState==4)
                {
                    alert('请求已完成');
                    if(xmlhttp.status==200){
                        document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
                        alert('成功地完成了任务');
                    }else if (xmlhttp.status==404){
                        alert('服务上未找到该文件');
                    }else if(xmlhtt.readyState==0){
                        alert('请示未初始化');
                    }else if (xmlhttp.readyState==2){
                        alert('请示已接收')
                    }else if (xmlhttp.readyState==3){
                        alert('请示处理中');
                    }
                }
            }
            xmlhttp.open("GET","hello1.txt",true);
            xmlhttp.send();
        }
    </script>
</head>
<body>
<div id="myDiv"><h2>使用AJAX修改该文本内容</h2>
    <button type="button" onclick="loadXMLDoc()">修改内容</button>
</div>
</body>
</html>

再次单击修改内容的按钮时会接连弹出关于Ajax请求的几个状态提示。

如果需使用async=false,就将open()方法中的第三个参数改为false,这时JavaScript会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢,应用程序会挂起或停止。

当使用async=false时,不需要编写onreadystatechange函数,把代码放到send()语句后面即可。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        function loadXMLDoc(){
            var xmlhttp;
            if(window.XMLHttpRequest)
            {
                //IE7+、Firefox、Chrome、Opera,Safari浏览器执行代码
                xmlhttp=new XMLHttpRequest();
            }
            else
            {
                //IE6、IE5浏览器执行代码
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.open("GET","hello.txt",false);
            xmlhttp.send();
            document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
        }
    </script>
</head>
<body>
<div id="myDiv"><h2>使用AJAX修改该文本内容</h2>
    <button type="button" onclick="loadXMLDoc()">修改内容</button>
</div>
</body>
</html>

20.3.2 Ajax的使用

在实际项目中使用Ajax与服务端交互,首先要约定传输数据使用的格式和规范,其中json数据格式是使用最为广泛的传输类型。一般的传输数据规范至少包含3个字段,即消息状态码(一般设置字段为status或code)、提示信息(msg)、消息体(data),当然字段的含义可由开发者根据需要自行设定。

一个Ajax请求服务端的示例代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        function loadXMLDoc(){
            var xmlhttp;
            if(window.XMLHttpRequest)
            {
                //IE7+、Firefox、Chrome、Opera,Safari浏览器执行代码
                xmlhttp=new XMLHttpRequest();
            }
            else
            {
                //IE6、IE5浏览器执行代码
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function () {
                //将json字符串转化为json对象
                var data=eval('(' + xmlhttp.responseText + ')');//转换为json对象
                if (xmlhttp.status==200) {
                    if (data.status == 0) {
                        document.getElementById("name").value = data['data'].name;
                        document.getElementById("age").value = data['data'].age;
                        document.getElementById("company").value = data['data'].company;
                    }else{
                        alert(data.msg);
                    }
                }else if(xmlhttp.status==404){
                    alert('服务器上未找到该文件');
                }
            }
            xmlhttp.open("GET","info.php",true);
            xmlhttp.send();
        }
    </script>
</head>
<body>
姓名:<input id="name"><br/>
年龄:<input id="age"><br/>
公司:<input id="company"><br/>
<button type="button" onclick="loadXMLDoc()">查询</button>

</body>
</html>

执行上面的程序将会向info.php发起请求。info.php里的代码如下:

<?php
$success = array('status'=>0,'msg'=>'success','data'=>array('name'=>'chenxiaolong','age'=>'22','company'=>'360 company'));
echo json_encode($success);

//$error = array('status'=>1,'msg'=>'nothing','data'=>'');
//echo json_encode($error);

我们定义status为0时表示数据正确,为1或其他状态时表示异常。客户端通过判断此字段的值来分别做出响应,data字段定义消息的具体内容。读者可将以上代码在电脑上编写一下,查看运行效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值