天天看点

《PHP精粹:编写高效PHP代码》——3.3节数据格式

本节书摘来自华章社区《php精粹:编写高效php代码》一书中的第3章,第3.3节数据格式,作者:(美)  davey shafik,更多章节内容可以访问云栖社区“华章社区”公众号查看

3.3 数据格式

在许多方面,web服务仅仅只是一个网页,它提供机器可读的内容,而不是人类可读的内容。我们与其在一个浏览器的html网页标记标签,不如返回内容到json或xml中(我们马上将论及上述内容)。

健壮性web服务的强大特征之一便是它的设计可使其以不同的格式返回信息。因此,如果一个服务消费者更喜欢另一种数据格式,它可以轻易请求到最好的格式。这表明,当我们创建的服务公开后,解释请求和构成响应的方式是独立于代码中其他部分的。

接下来的两节将详细讲解json和xml,并举例说明如何以这种方式格式化数据,以及我们如何读写数据。

3.3.1 使用json

json代表javascript object notation。它最初是表示javascript对象的一种方式,但是很多现代编程语言都具有使用这种格式的内置功能。这是基于文本、用来表示数组或对象的一种方式,类似于php的序列化。

json是一种轻量级的格式;数据包又小又简单,这使得我们可以快速轻松地处理它。由于我们将json设计用于javascript,因此它是javascript使用api的最佳选择;在本章后面内容中,你会看到在网页中使用ajax请求包含web服务内容的示例。json对于移动设备应用程序而言也是一种不错的选择;它的小体积和简单格式意味着它可快速传送数据,而且在客户端上我们只需简单处理就可以对它进行解码。

在php中,我们用json_encode()函数编写json,用json_decode()将它读取回来。这听起来很简单吗?可能因为json就是这么简单,下面是一个对数组编码的示例。

《PHP精粹:编写高效PHP代码》——3.3节数据格式
《PHP精粹:编写高效PHP代码》——3.3节数据格式

在这个示例中,我们仅通过json_encode()函数将字符串输出,再将它转换回来进入一个php数组。既然我们想要的是一个关联数组而不是一个对象,因此传入true作为json_encode()函数的第二个参数。若没有这些,我们会得到一个包含3个stdclass对象的数组,其中每个对象的属性名均为title和time。

从这些示例我们清楚地知道,在php中json的使用非常简单,它本身对于各种类型的web服务而言是一个非常受欢迎的选择。

3.3.2 使用xml

看过json的示例之后,让我们来看看另一种常用的数据格式:xml。xml表示可扩展标记语言(extensible markup language);在许多平台上它是表示机器可读数据的标准方式。

xml是比json更详细的一种格式。它包含更多数据类型的信息,不同的系统将使用不同的标记和属性详尽地描述信息。人们读到xml时会觉得很棘手,但它作为一种规范的格式在机器上使用是非常理想的。因此,当我们集成两个系统并交换无人管理的重要数据时,xml是一种很好的选择。

在php中,我们有很多方式使用xml,其中最重要的是dom扩展或simplexml扩展。这两种扩展在功能上有很多重叠部分;然而,简而言之,dom的可描述性更为强大而且复杂,而simplexml则非常简单!你可以调用单一的函数在两种格式之间切换使用,因此,当开始你使用一种方式,而后为了一个特殊操作而使用另一种方式是没有意义的。由于我们使用的是基本示例,所以这里将展示使用simplexml扩展的代码。

让我们像前面json一样开始下面的示例。

《PHP精粹:编写高效PHP代码》——3.3节数据格式

让我们从文件顶部开始讲解这个示例。首先,我们创建了一个simplexmlelement,它将一个标准格式的xml字符串传递给构造函数。如果我们想读取并使用现有的xml,这是非常重要的(当我们用xml数据解析传入请求,这确实非常便利),但是我们创建空元素时会感到有点古怪。

接着我们开始添加元素。在xml中,我们不能枚举条目,所有的东西都要放在一个已命名的标签内,因此每个音乐会的条目都要放在一个命名为concert的标签内。当我们继续添加子元素时,可以为这些子元素指定一个变量,这允许我们继续对这个变量进行操作。既然这样,我们要为concert标签添加更多的子元素,并将这些子元素存放在$concert1变量中,然后添加title和time标签作为子元素。

接下来我们可以对其他的音乐会重复以上操作(在一个实际的应用程序中,你可以使用循环结构从其他地方导入数据),然后使用simplexmlelement::asxml()方法输出xml。这种方法确实输出了对象代表的xml。

当我们读取这个xml时,你会觉得相当琐碎:

《PHP精粹:编写高效PHP代码》——3.3节数据格式
《PHP精粹:编写高效PHP代码》——3.3节数据格式
《PHP精粹:编写高效PHP代码》——3.3节数据格式

首先,我们载入xml到simplexml对象,这样就可以轻松地使用它。然后我们使用循环遍历里面的条目;我们可以使用foreach循环轻松迅速地遍历数据集。

如果我们在循环里通过var_dump()检查每一个$concert值,我们会看到它们实际上是simplexmlelement对象,而不是简单的数组。当我们输出$concert->title时,simplexml知道如何将$concert->title表示为一个字符串,因此,正如我们预期的那样,$concert->title输出对象的值。不管怎样,处理日期格式的数据很棘手!date()函数预计第二个参数是一个长数字,当你传入一个simplexmlelement来替代这个参数时会出现错误。你可能在以上示例中注意到这一点,我们将$concert对象的time属性进行类型转换为一个字符串。之所以这样做,是因为simplexmlelement知道如何将自己转换为字符串,而且如果我们提供一个字符串,php会用date()将其转换为正确的数据类型。

simplexmlelement对象类型

当你使用simplexml时,通常会发现这里有你预期值的对象。我们利用这个已使用的方法,在需要的地方将这些值进行类型转换,这是一个轻松使用那些值的好方法。

在这个示例结尾的地方还有一个“featured concert”,它表明simplexml对象是如何轻松穿过对象的结构找到我们想要的值。在我们使用xml数据和web服务时,在simplexml的特性和简单迭代能力之中,你会看到simplexml是工具盒中极好的一个工具。