计算机这门学科特别强调“实践出真知”。看IT开发的书籍如果不动手实践,大概在看完一个星期之后就只会记得看过这本书而已。对这一点,本人深有体会。所以读者最好是边看边做,这样看完之后也学会了。
群发消息。公众账号每天可以向订阅者群发一定量的消息。
使用编辑模式中的自定义回复消息,公众账号可以自定义一些消息回复规则。
使用开发模式,公众账号的维护者可以开发自己独特的业务逻辑来分析订阅者的消息,并反馈给订阅者。这个功能给了公众账号最大的自由度,使用好它可以极大地扩展公众账号的能力。
结合公众平台的特点和功能,公众账号可以有以下使用方法:
企业移动门户。订阅者可以通过企业账号获取最新的优惠和活动,例如“好乐迪KTV”、“百果园”、“海岸城”等公众账号都属于这一类。
娱乐。“糗事百科”、“百思不得姐”以及本书中将要介绍的"meiri10futu"等账号就属于这一类。
这个模式和多年前的手机订阅很像。在21世纪初,互联网在泡沫之后迎来了一种非常厉害的盈利模式—SP/CP模式,拯救了水深火热的互联网。当然,现在这种模式已经过时了,大家可以在网上了解一下那段互联网的历史。不过现实中还是存在真实的例子,如果你的手机号是中国移动的,可以参看10086的短信功能;如果你的手机号是中国电信的,可以参看10000的短信功能。笔者的手机号是中国电信的,当笔者想查询自己的套餐使用情况时,即可发送702到10001,10001会立即返回笔者的套餐详细使用情况。大家肯定猜到这条短信不是人工发过来的,而是由后台程序接到702之后查询中国电信自己的用户数据库后发过来的。同样的,中国移动的用户发送"YE"到10086查询余额的功能也是一样的。
图1-1所示的具体交互过程的描述如下:
2)后台收到这条消息之后,把消息转发给公众账号的后台,也就是公众账号的服务器;
通过这个过程可以看到公众账号服务器要做的事情有三件:
实现自己的业务逻辑;
接下来介绍一下开发环境的准备工作及生产环境的部署,如果读者已经知道如何使用AppServ可以跳过这些内容。
AppServ是一个软件集合,包括Apache(HTTP服务器软件)、PHP(网页程序设计语言)、MySQL(数据库管理系统软件)、phpMyAdmin(图形界面的数据库管理软件)四个组成部分,如图1-2所示。AppServ是一个HTTP服务的集成开发环境。AppServ把这些软件集合在一起的目的是使在Windows上部署整套环境变得更简单。
图1-2AppServ架构图
接下来介绍如何安装AppServ。
2)打开下载到的安装文件,单击"Browse"按钮选择安装位置,然后单击"Next"按钮,如图1-3所示。
图1-3选择安装位置
3)选择需要安装的组件,把四个组建都勾选上,如图1-4所示,然后单击"Next"按钮。
图1-4勾选需要安装的组件
图1-5配置HTTP服务器的ServerName和端口
注意127.0.0.1是计算机网络本地回环地址(LoopbackAddress)。网卡在接收到目的地址为127.0.0.1的网络包后会直接将该网络包回送给本地计算机。因此这个地址经常用来做测试。
5)配置MySQL服务器的root密码为一个熟悉的密码,保持字符集为UTF-8,勾选上"EnableInnoDB"选项,然后单击"Next"按钮,如图1-6所示。
图1-6配置MySQL的密码、字符集和数据引擎
注意InnoDB是MySQL的事务数据库首选引擎,支持ACID事务、行级锁定,自MySQL5.5起成为MySQL的默认数据库引擎。除了InnoDB外,MySQL还有很多其他的数据库引擎。
MyISAM是MySQL5.5之前的默认数据库引擎,最为常用,它拥有较高的插入、查询速度,但不支持事务。
BDB数据库引擎源自BerkeleyDB,是除InnoDB外事务型数据库的另一种选择,支持COMMIT和ROLLBACK等其他事务特性。
Memory数据库引擎把所有数据置于内存,拥有极高的插入、更新和查询效率。但是它会占用和数据量成正比的内存空间,并且其内容会在MySQL重新启动时丢失。
Merge引擎将一定数量的MyISAM表联合成一个整体,在超大规模数据存储时很有用。
Archive非常适合存储大量独立作为历史记录的数据,因为它们不经常被读取。Archive拥有高效的插入速度,但其对查询的支持相对较差。
6)等待安装完成,如图1-7所示。
图1-7等待安装完成
7)安装完成,勾选并启动Apache和MySQL,如图1-8所示。
图1-8安装完成,启动Apache和MySQL
图1-9验证AppServ是否安装成功
9)接下来验证phpMyAdmin是否安装成功。首先修改phpMyAdmin的配置,找到AppServ安装目录下的phpMyAdmin文件夹,进入该文件夹,找到如图1-10所示的config.inc.php和config.sample.inc.php两个文件。
图1-10AppServ安装过程:修改phpMyAdmin配置文件
10)把config.inc.php重命名为config.inc.php.bak,把config.sample.inc.php重命名为config.inc.php,然后打开新的config.inc.ini,设置$cfg['blowfish_secret']为任意的一个字符串,如图1-11所示。
图1-11修改phpMyAdmin配置
11)修改hosts配置。打开目录C:\Windows\System32\drivers\etc下的文件hosts,确保localhost没有被注释掉,如图1-12所示。因为phpMyAdmin是配置成通过localhost来访问MySQL服务器的,所以要确保localhost是解析到127.0.0.1的。
图1-12修改hosts配置
图1-14phpMyAdmin数据库管理页面
这就是MySQL的网页端管理工具AppServ的安装过程,AppServ几乎可以进行所有可视化的数据库操作。如果你还没有使用过,现在就可以试试它的功能。
最后介绍一下AppServ的安装目录,熟悉安装目录各个文件夹的作用,对稍后的开发有帮助。打开AppServ的安装目录,如图1-15所示。
图1-15AppServ的安装目录
图1-16www目录
可能读者此时已经跃跃欲试地想自己写一些PHP脚本了。不过不要这么着急,所谓工欲善其事,必先利其器。下面介绍一个非常好用的查看和编辑PHP脚本的IDE—zendstudio。它支持高亮显示,并有智能语法提示,可以大大提高开发效率。对于IDE,可以说是仁者见仁,智者见智。有的人说要充分利用IDE的一切功能,以提高开发效率;有的人说过度依赖IDE会使人忽略了语言的编译原理,因为编译、链接之类的事情IDE都智能化地做好了。这两种说法都没有错,笔者的建议是,把IDE当作一个写代码的工具,因为IDE的智能语法提示和高亮显示可以提高开发效率,其他的事情还是自己来做会比较好。尽管IDE已经很智能,但是还是会经常犯一些很低级又不易察觉的错误。本书也是只把zendstudio当作一个写代码的工具。大家慢慢就会体会到这么做的好处。
zendstudio是ZendTechnologies开发的PHP语言集成开发环境,是一款收费软件,不过试用版本有30天的试用期。可以去ZendTechnologies的官网随便下载任意的试用版,因为我们需要的高亮显示和智能提示在每个版本中都有。笔者用的是一个以前下载好的6.1版本。它的安装非常简单,按照安装指引来就可以了。下面简单介绍一下zendstudio的安装过程。
1)打开安装程序,然后单击"Next"按钮,如图1-17所示。
图1-17打开zendstudio安装程序
2)这里有一个选择安装位置的选项,可以按照自己的喜好选择安装的硬盘位置。然后不停单击"Next"按钮,直到安装结束,最后得到一个如图1-18所示的欢迎页面。
图1-18zendstudio安装完成的欢迎页面
3)关闭该欢迎页可以看到一个已有的ExampleProject,因为我们不需要这个示例项目,所以删除它。在此项目上右击,在弹出的快捷菜单中选择"delete"选项,在接下来弹出的对话框中勾选"Deleteprojectcontentsondisk"(删除项目文件)选项,如图1-19所示,然后单击"OK"按钮,完成项目删除。
图1-19删除ExampleProject
4)接下来我们创建一个测试项目,为学习PHP、HTTP、MySQL、XML做好准备。将项目命名为Test,单击菜单"File",然后选择"new"选项,接着单击"PHPProject"选项,在弹出的新建项目对话框(如图1-20所示)的"Projectname"文本框中输入"Test",之后在Contents下取消勾选"Usedefault"选项,接着单击"Directory"文本框后的"Browse"按钮,定位到AppServ安装目录下的www文件夹,然后再手工输入"\Test"。最后单击"Finish"按钮,完成这个项目的创建。
图1-20创建Test工程
5)打开AppServ的安装目录下的www文件夹,可以看到一个新的文件夹,其和phpMyAdmin并列,如图1-21所示。
图1-21新建工程对应的目录
PHP是一种创建动态交互站点的强有力的服务器端脚本语言。PHP语法非常类似于Perl和C。PHP常常搭配Apache(web服务器)一起使用,不过它也支持ISAPI,并且可以运行于Windows的微软IIS平台。
1.PHP的基本语法
PHP的脚本块以"<php"开始,以“>”结束。可以把PHP的脚本块放置在文档中的任何位置。当然,在支持简写的服务器上,可以使用“<”和“>”来开始和结束脚本块。不过,为了达到最好的兼容性,推荐使用标准形式(<php),而不是简写形式。下面的代码就是PHP脚本的一个简单应用,其实现的是打印一个简单的字符串:helloworld!。
右击Test工程,在弹出的快捷菜单中选择"New"选项,然后选择"PHPFile"选项,在弹出的“新建PHP文件”对话框的"FileName"文本框中键入"test.php",单击"Finish"按钮。接着在新建的test.php文件里输入以上代码,并通过Ctrl+S快捷键保存,如图1-22所示。
图1-22test.php
图1-23test.php在googleChrome中的运行结果
test.php文件的创建和运行展示了最基本的使用Apache和zendstudio开发和测试PHP脚本的过程:
1)在zendstudio中创建文件,并编写相应的代码。
2)在浏览器中运行脚本,查看脚本输出是否正确。如果代码有语法错误或者出现了异常,浏览器会打印出语法错误提示和抛出的异常描述。
本书中的所有PHP代码都是这样编写并调试的。
PHP的注释和C语言的注释是一致的,用“//”作为单行注释的开始,用“/*”和“*/”包含多行注释,如图1-24所示。
图1-24单行注释和多行注释
2.PHP的变量
上述代码的分析如下:
echo"<BR>"是打印一个网页换行符。
注意其中的echo"$a,$b"和echo'$a,$b',对应不同的输出。在双引号中变量会自动解析成它的值,而在单引号中,变量不会做任何转义。这和Shell脚本是一致的。
图1-25test2.php的执行结果
PHP中有一个非常简便的连接操作符:.(一个英文的句号)。它可以连接字符串,当操作数中有非字符串时,会先转换成字符串,然后再做字符串连接操作。继续上面的例子,我们在上面代码的末尾加入以下代码:
在浏览器中执行修改后的代码,结果如1-26所示。
图1-26连接操作符的结果
可以看到其他$a和$b的连接形成了"5thisisastring",$a先转成了一个字符串再和$b做连接操作。在语句$a.$a中,连接操作符两边的$a都被转成了字符串再做连接操作,于是得到结果“55”。
3.PHP的运算符
PHP的运算符包括算术运算符、赋值运算符、比较运算符和逻辑运算符。这些运算符的定义和C、C++和Java中的都是一样的,本书不做详细介绍,下面以表格的方式列出这些运算符的定义。
算术运算符,其具体定义如表1-1所示。
赋值运算符,其具体定义如表1-2所示。
比较运算符,其具体定义如表1-3所示。
逻辑运算符,其具体定义如表1-4所示。
4.PHP数组
PHP的数组和其他语言的有很大的不同,这也是PHP语言的特色之一。PHP有三种类型的数组:数值数组、关联数组和多维数组。
(1)数值数组
数值数组存储的每一个元素都带有一个数值ID键,这和C、C++、Java中的数组是一样的。可以使用不同的方式来创建数值数组,例如下面这种定义方式:
这种以定义一个array的方式创建的数组,系统会自动为数组中的每个值分配一个从0开始的键值。它等同于下面的方式:
下面我们测试一下采用上面这种方式新建的数组,建立新的测试文件或者删除test2.php文件中的代码,输入下面的代码:
在浏览器中测试,结果如图1-27所示。
图1-27数组测试结果
可以把数组的定义方式换成使用array的方式,得到的结果是一样的。需要注意的一点是数组中各个元素的类型不需要一样。可以定义以下的数组:
这是PHP语言和其他语言(C/C++/Java)相比最大的不同之处。
(2)关联数组
和数值数组不同,关联数组的key可以为整型或者字符串。和数值数组一样,关联数组也有两种定义方式。下面展示的是第一种方式:
下面第二种方式:
这和下面的定义是一致的:
(3)多维数组
在多维数组中,如果主数组是一个数值数组,那么它的元素还可以是一个数组(关联数组或者数值数组),如下面的代码所示:
如果主数组是一个关联数组,那么它的value可以是一个数组(关联数组或者数值数组),如以下代码所示:
PHP的数组是PHP中最灵活的数据类型,可以任意组合各种数据类型,下面的数组也是合法的:
PHP会为没有key的元素自动分配一个从0开始的key值,上面代码中创建的数组中的元素'hello'的key为0,'sheep'的key为1。为了证实这个结论,我们先引入两个PHP的内建函数var_dump和var_export。
5.常用函数
(1)var_dump和var_export
var_dump可以把变量以字符串形式打印出来,而var_export可以把变量以字符串形式打印出来或者返回。先看下面的代码:
执行结果如图1-28所示。
图1-28var_dump测试结果
仔细查看图1-28中的输出,最开始的"array(4)",表明var_dump函数的入参"$srr"是一个大小为4的数组(数组第一维的长度为4)。接下来的一个花括号包含的是这个数组的说明,数组的每一个元素的key都在一个中括号中,然后每个元素的value是由类型和它的值组成的。仔细观察数组中每个元素的下标:第一个元素"hello"的下标为0,最后一个元素"sheep"的下标为1;其他的元素的下标都是我们在程序中指定的。这证实了我们的结论:对没有设定下标的元素,PHP会自动为它们设定从0开始的下标。
var_export函数和var_dump类似,不同之处是它接受第二个参数:一个bool值(true/false)。当var_export不传入第二个参数的时候,它输出变量的字符串表示的是和var_dump的类似(此时第二个参数的为默认值false)的。当设定第二个参数为true时,它会把变量的字符串当作返回值返回,而不是直接输出。看下面的例子:
执行结果如图1-29所示。
图1-29var_export的输出
仔细观察var_export的输出会发现,和var_dump的输出不同之处是它不输出类型信息。但是这些类型信息基本上可以一眼看出。
(2)file_put_contents
file_put_contents是一个可以写字符串到文件的函数,有四个入参,但我们只要关心前三个。第一个入参是表示文件地址的字符串;第二个是需要写入的字符串;第三个是写入的模式,我们一般用宏定义FILE_APPEND,表示追加写入。看下面的例子。
执行这段代码,然后打开文件tmp.txt,查看file_put_contents输出,如图1-30所示。
图1-30file_put_contents输出
我们在执行这段之前并没有手工建立tmp.txt文件,这说明file_put_contents在没有文件的情况下会自动创建文件。另外var_export的输出和在Chrome里输出的不一样,文件里的格式更好看,因为对齐了。这是因为var_export是用ASCII码中的\t和\n来做对齐处理的,但是这些字符串的意义在浏览器中是不能正常解析的,但是在文本处理器editplus中可以正常解析。
PHP的基本语法就介绍到这里,它的其他的特性和其他语言相差不大,在后面介绍其他预备知识和具体使用到的时候再介绍。
笔者在meiri10futu的部署机器上运行tcpdump抓包,图1-31是抓到并用wireshark分析的一个完整的请求和返回包。
图1-31公众平台服务器的HTTP请求和返回包
请求分为头部(head)和正文(body)两部分,数据之间用一个空行分割(实际上是两个"\r\n"),即上面的"Keep-Alive"下面的空行之后的数据为body,之前的部分为head。接下来我们来看GET数据和POST数据在哪里。
(1)HTTP请求中的GET数据
注意上面的请求数据中的第一行中如下的数据:
这些用“&”分隔的字符串就是GET数据,我们把用“&”分割之后的字符串列出来:
signature=771f6bd01508e46b02061b0a1330a6ad67e1ad77
timestamp=1364458805
nonce=1364226029
这样看起来就非常清楚了,等号左边是GET数据的key,右边是GET数据的value,具体如何在PHP程序中获取这些GET数据,等讲完POST数据之后会有一个统一的例子。
(2)HTTP请求中POST数据
上面请求中的body部分就是POST数据,POST数据和GET数据不同,它不会有key值。POST数据一般都比较大,GET数据往往比较小。下面的程序展示了如何获取GET数据和POST数据。我们把test2.php的内容改成如下形式:
然后我们使用Fiddler的RequestBilder向test2.php发一个POST请求,请求中带的GET数据及POST数据和上面的示例一样,如图1-32所示。
图1-32用Fiddler向test2.php发POST请求
然后查看tmp.txt中的输出,如图1-33所示。
图1-33GET和POST数据在文本中的输出
注意在Fiddler中输入GET数据时不是在RequestHeader输入框中输入,而是在请求URL后先输入一个问号,然后输入所有的GET字符串。
可以看到,$_GET是一个数组;key是各个GET数据的key;$HTTP_RAW_POST_DATA是一个字符串,包含body的所有内容。在设置这些变量的同时,Apache还为我们设置了一个$_POST变量,它是用来存前台HTML的form表达提交的数据,本书使用不到。大家不要误以为$_POST变量是我们想要的POST数据,一定要区分开。
注意我们在这里没有使用editplus来打开tmp.txt,而是用的写字板。如果你试了用editplus打开的话会发现,脚本中我们特意输出和var_export自动输出的"\n"都没有当成换行符来显示,使得格式很难看。这是因为当文件中既有"\r\n"又有"\n"时,editplus会自动选择其中的一种作为换行符,而忽略其他的方式。在打开tmp.txt时editplus就选择了HTTP的body中的"\r\n"作为换行符而忽略了"\n"。
在这一小节中我们用到了三个非常有用的工具:
1)tcpdump是一个Linux上的抓包命令,有非常多的选项和表达式。可以结合自己的需求,使用相应的选项和表达式来抓取需要的网络包。
2)wireshark是一个Windows上的抓包工具。它的功能和tcpdump是一样的,但是它的优点在于其图形化界面,对数据包的可视化做得非常好,同时也能打开tcpdump的数据包文件。我就喜欢用tcpdump在Linux机器上抓包之后再到Windows上用wireshark打开来分析。
使用好这些工具对于自己的工作和学习有非常大的帮助。有兴趣的读者可以到网络上搜索这些工具的高级教程。
PHP为我们提供了一个很简单的函数来解析XML—simplexml_load_string。它接受五个参数,第一个是需要解析的XML字符串,其他四个参数都是可选的。在解析成功的时候会返回一个SimpleXMLElement的对象,如果解析失败则返回false。一般在入参中传入的XML数据不符合规范的时候才会解析失败进而返回false。代码清单1-1所示的例子展示了如何使用simplexml_load_string来解析XML。这个例子继续上一节,我们用simplexml_load_string来解析$HTTP_RAW_POST_DATA,并输出解析后的数据。
重新按照上一节的方法,用fiddler向test2.php发送请求,然后单击选中fiddler左边的请求列表中对应到这次请求的条目,双击,在右侧会显示请求的详细返回信息,如图1-34所示。
图1-34fiddler中的请求test2.php的结果
可以在图1-34所示界面右下侧的TextView中看到我们在程序中echo的输出。可以看到我们是通过对象$xmlObj的成员变量来访问XML的条目的,引用成员的方式和C++中通过对象指针访问它的public成员变量是一样的。PHP的对象在本书后面的实例中会用到。限于篇幅,这里不过多介绍,读者可以查阅其他资料做更多的了解。
注意在代码清单1-1中判断simplexml_load_string的结果是否为false使用的是三个等于号“===”。这是PHP的“全等于”符号,只有当全等号左边和右边的表达式的大小和类型完全相等时才返回true。虽然PHP是弱类型语言,但并不表示变量没有类型。两个等于号(“==”)只能判断两边的值是否相等。在两个等于号的情况下:false、空字符串、空数组、0都是相等的。但是使用全等号的判断可以把它们区分开,因为它们的类型不相同。
MySQL是开源的关系型数据库,我们介绍它是因为在后面的案例中,需要存储用户信息的时候会用到它。相信很多人在学习数据库的时候都学过SQLServer,MySQL和它类似,都支持数据存储和SQL语句查询。和SQLServer相比,MySQL显得更轻便简洁,并且移植性更好。对于MySQL来说,Windows的版本和Linux的版本使用方法完全一样。
Java和.NET等语言在访问数据库的时候通常都是通过一些封装好的dbconnector或者driver实现的,PHP也一样。PHP访问MySQL的封装库有三种连接方式:ext/mysqli、PDO_MySql和ext/mysql。ext/mysqli是ext/mysql的增强版(i代表improved),并且ext/mysql已经不再做升级了,因此不推荐使用ext/mysql。表1-5详细比较了这三种连接MySQL封装库方式的异同。
本书中使用ext/mysqli来访问MySQL,下面就描述一下如何使用ext/mysqli。ext/mysqli的每个函数都包含一个面向对象风格的函数和一个过程化风格函数。这以过程化风格的函数为例进行讲解。连接并发起对MySQL数据库的查询,一般有以下几个步骤:
1)使用mysqli_init初始化ext/mysqli,这个函数会返回一个ext/mysqli资源,用来做下一个函数的入参。
2)使用mysqli_real_connect打开一个对MySQL服务器的连接,这个函数需要MySQL服务器的地址、端口、数据库名、用户名和密码。
3)使用mysqli_query进行查询SQL语句的操作。
4)如果上一步中的返回结果是一个数据集(select操作的返回),可使用mysqli_fetch_array获取返回结果集。这个函数有两个参数:第一个参数用于表示mysqli_query的返回数据集;第二个参数用于描述mysqli_fetch_array的返回是关联数组(MYSQLI_ASSOC)、数值数组(MYSQLI_NUM)或者两种都返回(MYSQLI_BOTH),两种都返回是默认方式,不过我们这里使用第一种方式,只返回关联数组。
5)使用mysqli_close关闭和数据库的连接,这个步骤可以省略,因为PHP在脚本执行完毕的时候会释放并关闭所有的fd,其中也包括对数据库的连接。
图1-35使用phpMyAdmin创建test2数据库
数据库创建完成后会进入数据库test2的管理界面。在管理界面中选择名为SQL的tab,在输入框中输入建表语句,如图1-36所示。
图1-36使用phpMyadmin创建表test
可以看到使用phpMyAdmin管理MySQL数据库非常方便,现在已经有了数据库和数据表,我们在zendstudio中把test.php的代码替换成以下形式:
在Chrome中执行上面的程序,结果如图1-37所示。
图1-37数据库操作示例的执行结果
我们在程序的最后并没有调用mysqli_close,这也是大部分的脚本的做法。当然如果你坚持认为这样不好,并一定要加上它,那也是没有问题的。
相比HTML4,HTML5有以下的一些新的特性:
语义特性,HTML5赋予网页更好的意义和结构。随着HTML5对RDFa的微数据与微格式等方面的支持,其所支持的标签将更加丰富,其将可构建对程序、对用户都更有价值的数据驱动的Web。HTML5提供了更多的标签,表1-6是这些新增标签的简介。
设备兼容特性。自从Geolocation功能的API文档公开以来,HTML5为网页应用开发者们提供了更多功能上的优化选择,带来了更多体验功能的优势。HTML5提供了前所未有的数据与应用接入开放接口,使外部应用可以直接与浏览器内部的数据直接相连,例如视频影音可直接与microphones及摄像头相连。
连接特性。更有效的连接工作效率,使得基于页面的实时聊天、更快速的网页游戏体验、更完美的在线交流得到了实现。HTML5拥有更有效的服务器推送技术,Server-SentEvent和WebSockets就是其中的两个特性,这两个特性能够帮助我们实现服务器将数据“推送”到客户端的功能。服务端推送技术一直是Web端服务的难题。现有的技术有基于长连接的COMET、内嵌flash、基于ajax的长轮询,这些都有各自的缺点,不是HTML原生支持的。
网页多媒体特性。支持网页端的Audio、Video等多媒体功能,与网站自带的APPS、摄像头、影音等功能相得益彰。
三维图形及特效特性。基于SVG、Canvas、WebGL及CSS3的3D功能,用户会惊叹于在浏览器中所呈现的视觉效果。
性能与集成特性。没有用户会永远等待你的Loading—HTML5会通过XMLHttpRequest2等技术,帮助您的Web应用和网站在多样化的环境中更快速地工作。
CSS3特性。在不牺牲性能和语义结构的前提下,CSS3中提供了更多的风格和更强的效果。此外,较之以前的Web版本,HTML5的开放字体格式(WOFF)也提供了更高的灵活性和控制性。
在Chrome中执行上述PHP文件,结果如图1-38所示。
图1-38使用canvas画一个红色圆
仔细观察上面JavaScript代码中对变量cxt的使用,会发现这些函数调用方式和openGL的一些基本函数很像。Canvas给了浏览器画图的能力,提供了图形学的一些基本函数,基于这些基本函数,开发者可以开发出复杂的二维、三维的应用。