php数据处理

PHP如何实现一个高效的数据库

用文件的方式读写,一个文件是索引文件,另一个文件是真实的数据文件。

索引文件分为2部分,第一部分是所有的指针,记录第二部分的位置;第二部分是索引记录。所有的索引指针:是记录所有相同Hash值的key的指针,它是一个链表结构,记录在数据文件的位置和同key的下一个值。

索引记录中:每条记录有四部分,第一部分4个字节,是下一条索引的偏移量;第二部分是该记录的key,128字节;第三部分是数据偏移量,4个字节;第四部分是数据记录长度,4个字节。

我们设定文件的存储上限为262144个。

查找流程如下:

1、根据key算出hash值,获取该hash值的链表在索引文件的第一部分(所有指针区)的位置。

2、根据步骤一的位置,获取值,时间复杂度O(1);

3、根据步骤一中的值,找到索引文件中第二部分(索引记录)的位置,也就是和key相同hash值的所有指针的链表。顺着链表查找该key,获取该key在链表中存放的数据,数据只包含该key在索引文件中的位置,时间复杂度为O(n);

4、根据步骤二所获取的key在索引文件位置,得到索引文件中存放该key的信息。信息包含在真实数据文件中存放真实数据的位置。

5、根据步骤三所获取的位置,在真实数据文件中获取数据,并返回给应用程序。

测试结果:插入10000条耗时:793ms。查找10000条耗时:149ms。虽然这效率只有Redis的十分之一。。。但是请不要在意这些细节。

代码做了注释,上述文字有些乱。代码只实现三个方法,一个插入(如果存在则跳过),一个是查找,一个是删除。

展开
收起

基于layui和thinkphp数据表格的数据接口请求异常解决方案

前段时间,想用现阶段比较火的前端UI框架(layui)搭配thinkphp设计一个系统后台,但是用到数据表格读取数据的时候出现了接口异常,看了官方文档之后还是不解其中之奥妙。然后就去layui社区看了出现同样问题的帖子,大部分回答都比较模糊,也没有给出一个详细的解决方案。接口出现异常如图所示:

经过反复查看文档教程以及测试以后,原来是返回的json格式问题,layui对json格式要求严谨,所以朋友们在对数据组装的时候一定按文档给出的格式来写。成功读取数据如图:

前端代码如图所示:

后端代码如图所示:

展开
收起

PHP操作MySQL-SQL注入及附录「程序员培养之路第五十二天」

SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。SQL注入通常由于执行sql语句时,没有对用户通过Web表单提交的参数或者查询的字符串没有进行特殊字符过滤等,导致欺骗服务器执行恶意SQL命令。

为了防止这种情况,写脚本文件的时候,通常会考虑防止SQL注入,最简单的办法就是使用预处理语句,因为预处理语句事先已经编译了语句,传递的参数是不参与解释的。

PHP

附录:

PHP的报错级别

$_SERVER参数

PHP操作MySQL-解析结果集「程序员培养之路第五十一天」

PHP操作MySQL-预处理语句「程序员培养之路第五十天」

PHP操作MySQL-其他「程序员培养之路第四十九天」

展开
收起

PHP八种数据类型

在PHP程序中,数据类型可以分成3种:标量数据类型、复合数据类型(即将多个简单数据类型组合在一起,存储在一个变量名中)和特殊数据类型。1.标量数据类型标量数据类型包括以下几种。(1)boolean:布尔型 布尔变量是PHP变量中最简单的。它保存一个True或者False值。其中True或者False是PHP的内部关键字。设定一个布尔型的变量,只需将True或者False赋值给该变量(2)string:字符串 字符串是连续的字符序列,字符串中的每个字符只占用一个字节。在PHP中,定义字符串有3种方式:单引号方式,双引号方式,Heredoc方式。(3)integer:整数 整数数据类型只能包含整数。这些数据类型可以是正数或负数。在32位的操作系统中,有效的范围是2 147 483 648~+2147 483 647。(4)double:浮点数 浮点数据类型可以用来存储数字,也可以保存小数。它提供的精度不整数大得多。在32位的操作系统中,有效的范围是1.7E-308~1.7E+308。

2.复合数据类型复合数据类型包括以下两种。(1)array:数组可以是二维、三维或者多维,数组中的各元素可以是string、integer或double,也可以是array。(2)object:对象类型

3.特殊数据类型特殊数据类型包括以下两种。(1)resource:资源 资源是PHP内的几个函数所需要的特殊数据类型,由编程人员来分配。(2)null:空值 空值是最简单的数据类型。表示没有为该变量设置任何值,另外,空值(NULL)不区分大小写。

展开
收起

php如何给一组数据分页

我们在处理数据的时候有时候由于页面内容太多而需要对其进行分页,一下为我个人对于数据分页的理解。

分页

1.定义数组数据

$data =[ 'aaa','bbb','ccc','ddd','eee','fff','gggg','hhhh'];

2.计算数据总数

$total =count($data); //数据总量

3.定义当前页面

$currpage=$currpage ?? 1; //默认分页为第一页

4.计算总分页数量

$pagetotal =(int)ceil($total/$pageSize); //总分页数

5.计算起始位置

$start = ($currPage-1)*$pageSize;

$end = $total > $pageSize ? $pageSize : $total ;

6.对数据进行整合

$arr['total'] =$total;

$arr['currpage'] = $currPage;

$arr['pagesize'] = $pageSize;

$arr['pagetotal'] = $pagetotal;

$arr['list'] =array_slice($data,$start,$end); //对数据进行分割

//字符串内容可以使用 substr($data,$start,$end);

最后

return $arr; //最后输出数据

展开
收起

PHP操作MySQL-其他「程序员培养之路第四十九天」

解析结果集

PDO(PHP Data Object)

PDO是PHP数据对象的英文缩写,英文全称为PHP Data Object,是又MySQL官方封装的、基于面向对象编程思想的、使用C语言开发的数据库抽象层。

配置PDO

Windows下启动PDO需要在“php.ini”文件中进行配置,添加扩展:

extension=php_pdo.dll

在最新版PHP中,PDO已经默认开启,只需要启动其他数据库扩展即可。配置好这些后重启Apache服务。执行phpinfo()函数,看到PDO配置项,说明开启成功。

MySQL

访问数据库

与mysqli扩展类似,PDO扩展也是实例一个PDO对象,然后可以调用相关方法和属性来执行数据库的操作。

连接服务器

使用PDO与服务器建立连接,需要先使用构造方法来创建PDO实例,PDO的构造方法如下:

_construct(stringdata_source_name [,string user[,string pwd[,array driver_options]]])

datasourcename : 数据源,该参数包括了数据库名,主机名。MySQL数据库的DSN为:“mysql:host=localhost;dbname=account_db; port=3306”

user:数据库服务器用户名

pwd:为数据库服务器密码

数据库连接成功后,将返回一个PDO的实例,连接失败将会抛出一个PDOException异常,通常会使用try/catch语句进行处理。

关闭数据库

要想关闭连接,需要销毁对象以确保所有到它的引用都被删除,可以给变量赋一个NULL。

执行SQL语句

PDO提供了三种执行SQL语句的方法,分别是exec(),query(),预处理语句。

exec()

exec()方法可以执行一条语句,并返回受影响的行数,它的语法格式如下:

int PDO::exec(String sql)

exec()方法通常用于insert into,delete,update等语句。

<?phpecho "<pre>"; $dbms = "mysql"; $server = "localhost"; $username = "root"; $password = "123456"; $dsn = "$dbms:host=$server"; try { $pdo = new PDO ( $dsn, $username, $password ); echo "PDO连接MySQL数据库服务器成功"; print ($pdo->exec ( "create database account_pdo_db" )) ; print ($pdo->exec ( "use account_pdo_db" )) ; print ($pdo->exec ( "set names utf8" )) ; print ($pdo->exec ( "create table account(id int auto_increment primary key, username varchar(50) not null, password varchar(50) not null, email varchar(50) not null)" )) ; print ($pdo->exec ( "insert into account(username, password, email) values ('Jack', '123456', 'jack@example.com')" )) ; print ($pdo->exec ( "insert into account(username, password, email) values ('Lucy', '123456', 'lucy@example.com')" )) ; $pdo = null; } catch ( PDOException $e ) { echo "PDO连接MySQL数据库服务器失败"; die (); }?>

query()

query()方法不同于exec(),通常用于select语句中,它的返回值是PDOStatement的实例,是POD里的结果集。它的语法如下:

PDOStatement PDO::query(String sql)

<?phpecho "<pre>";$dbms = "mysql";$server = "localhost";$username = "root";$password = "123456";$dbname = "account_pdo_db";$dsn = "$dbms:host=$server;dbname=$dbname";try {$pdo = new PDO ( $dsn, $username, $password ); echo "<p>PDO连接MySQL数据库服务器成功</p>"; $result = $pdo->query ( "select * from account" ); foreach ( $result as $row ) { var_dump ( $row ); } $pdo = null;} catch ( PDOException $e ) { echo "PDO连接MySQL数据库服务器失败"; die ();}?>

展开
收起

PHP数组合并之Excel读的数据还能这么处理 - 带你玩转PHP函数系列

在PHP开发的时候,说到合并数组,我们通常想到的数组函数就是array_merge(),可是有时候我们会遇到这种情况,比如说读取Excel文件的时候,获取回来的数据是一行一行的数组,表头也是单独一行,这个时候,我们希望把表头作为键名和表内容对应起来合并成一个 表头=>内容 的数组,使每一行都能根据表头取值,那么如何实现呢?

开发工具/浏览器

PHP开发环境(本文使用的是WAMP)

代码编辑器(本文用的是PHPstorm)

谷歌浏览器

步骤/流程

1.首先我们需要创建一个模拟读取回来的Excel数据数组,代码及浏览器运行效果如图

2.要实现我们想要的效果,我们需要用到array_combine()函数,该函数具体说明如图所示

3.使用array_combine()函数,需要传入两个数组,第一个数组作为键名,第二个数组作为键值,我们循环示例数组,把表头作为键名与内容映射,使每一行都能根据表头取值,代码及浏览器运行效果如图

4.使用array_combine() 函数,合并的两个数组元素个数必须相同,否则返回的是False

5.总结

1).使用array_combine()函数,需要传入两个数组,第一个数组作为键名,第二个数组作为键值

2).使用array_combine() 函数,合并的两个数组元素个数必须相同,否则返回的是False

注意事项

PHP有很多实用的函数是大家以前忽略掉的,本系列的文章会为大家详细介绍所有PHP函数

希望本系列的文章能够给大家带来帮助节省大家解决问题的时间

展开
收起

php数据类型有哪些?

大家好,欢迎关注支持,谢谢!本篇将介绍php数据类型有哪些?有兴趣的朋友可以了解一下!

一、前言

php是一门很受欢迎的编程语言,而且简单易学,因此迎来了很多自学者,小编也是其中一个。每一门编程语言都有自己的数据类型,php也不例外,也有自己的数据类型。但是php和其它语言不一样,它是一门弱语言,在声明变量的时候不需要指定数据类型。所以,关于php数据类型我们只要了解就可以了,并不需要记忆,这也是php语言简单易学的表现之一。

虽然php声明变量并不需要指定数据类型,但是在声明一个变量的时候,我们应该要知道它是什么数据类型,以便能更正确更灵活的使用它。所以,小编认为了解php数据类型也是很有必要的。况且,在今后如果要找工作,在笔试或面试中也很有可能会遇到。

关于php数据类型,小编并不建议大家去死记硬背。虽然背下来并不是一件难事,但是死记硬背下来的东西时间一久就自然忘记了。还是建议大家在实际应用中想一想它,比如:在声明一个变量中,就要明白该变量是一个什么数据类型。这样久而久之就自然地记住了,而且还不容易忘记。

今天小编结合自己的理解和平时自学的笔记,对php数据类型进行了总结。在此借助百家号这个平台分享给大家,希望对大家有所帮助!

二、php数据类型

在php中,有八种基本的数据类型,四种标量类型、两种复合类型和两种特殊类型。数据类型一般是在声明变量的时候由程序员指定,但是php不一样。php是一门弱语言,变量的数据类型不需要程序员指定,php会根据该变量使用的上下文在运行的时候指定。

四种标量类型整型(integer):取值有效范围是-2147483648到+2147483647。整型可以由三种格式来表示:十进制,十六进制或八进制表示。十六进制需要加前缀0x,八进制需要加前缀0。整型数据其实就是我们数学中所说的整数,包括正整数、负整数和0。浮点型(float/double ):取值有效范围是1.8E-308到1.8E+308。浮点数据类型的变量可以用来存储整数和小数,精确度比整型数据类型要高。字符串(string):字符型变量在php中用的非常多,它可以用来存储字符和字符串。在其它语言中,字符和字符串是两种不同的数据类型。但在php中,统一使将字符和字符串当作字符串数据类型。布尔型(boolean):布尔型数据只有两种取值,TRUE和FALSE(不区分大小写)。

四种标量类型的使用:

<?php

header("content-type:text/html;charset=utf-8");//设置编码,解决中文乱码

$int = 100;//整型

$flo = 3.14;//浮点型

$str = "字符串数据类型";//字符串

$boo = TRUE;//布尔型

var_dump($int);//输出类型和值

var_dump($flo);

var_dump($str);

var_dump($boo);

?>

运行结果:

四种标量类型

两种复合类型数组(array):数组是一个很特殊的数据类型,可以在一个变量中存储多个数据。在php中,使用array()函数来创建数组。对象(object):对象也是一种特殊的数据类型,是存储数据和有关如何处理数据的信息的数据类型。在php中,创建对象用new关键字。两种复合类型的使用:

<?php

header("content-type:text/html;charset=utf-8");//设置编码,解决中文乱码

class People{//类

var $name; var $age;//成员变量

function say(){//方法

echo "我的名字叫:".$this->name."<br>";

echo "我今年".$this->age."岁<br>";}}

$arr = array("数组","对象");//创建数组

$obj = new People();//创建对象

$obj->name = "小明";$obj->age = 25;//对象属性赋值

$obj->say();//调用对象方法

var_dump($obj);//输出数组

?>

运行结果:

两种复合类型

两种特殊类型资源(resource):资源数据类型保存了到外部资源的一个引用(如:打开文件、数据库连接等),是通过专门的函数来建立和使用的。NULL(NULL):NULL数据类型唯一可能的值就是NULL,用来表示一个变量没有值。两种特殊类型的使用:

<?php

header("content-type:text/html;charset=utf-8");//设置编码,解决中文乱码

$fp = fopen("test.txt", "rw");//资源类型

$str = "null类型";//字符串

$str = NULL;//NULL类型

var_dump($str); var_dump($fp);//输出

?>

运行结果:

null

resource(3, stream)

运行结果说明:3::资源ID为3,tream:资源类型名称s。具体含义今后介绍。

好了,关于“php数据类型有哪些?”的介绍就到此结束了,希望能帮助大家!

展开
收起

PHP操作MySQL-预处理语句「程序员培养之路第五十天」

PDO提供对预处理语句的支持。

预处理语句是预先将一个预处理的sql语句发送到数据库服务器,执行其他sql语句只是修改预处理语句里对应的参数。简单的说,就是将sql语句强制一分为二:第一部分为前面相同的命令和结构部分,第二部分为后面可变的数据部分。预处理语句,可以减轻数据库服务器压力。

MySQL

定义预处理语句

使用prepare()方法执行sql预处理语句,得到一个PDOStatement实例,sql预处理语句通常有如下两种定义方式:

命名参数:自定义的有意义的字符串作为命名参数,前面加上冒号。insert into table_name(name,password,email) values(:name,:password,:email)

问号数据占位符:使用“?”作为参数。insert into table_name(name,password,email) values(?,?,?)

绑定参数

往预处理语句绑定参数有三种方法:

bindParam()方法一个一个绑定,绑定完成执行execute()方法使之生效。bindValue()方法一个一个绑定,绑定完成执行execute()方法使之生效。直接使用execute()方法传递一个数组,命名参数使用关联数组,数据占位符使用索引数组。<?php echo "<pre>"; $dbms = "mysql"; $server = "localhost"; $username = "root"; $password = "123456"; $dbname = "account_pdo_db"; $dsn = "$dbms:host=$server;dbname=$dbname"; try { $pdo = new PDO ( $dsn, $username, $password ); echo "PDO连接MySQL数据库服务器成功"; // 数据占位符 $pre = $pdo->prepare("insert into account(username, password, email) values (?,?,?)"); $name = "Peter"; $pwd = "333333"; $pre->bindParam ( 1, $name ); $pre->bindValue ( 2, $pwd ); $pre->bindValue ( 3, "Peter@example.com" ); $pre->execute (); $name = "张三"; $pre->execute (array($name,"1245","zhangsan@example.com")); // 命名参数 $pre = $pdo->prepare("insert into account(username, password, email) values (:name,:pwd,:email)" ); $name = "老王"; $pwd = "00544abc"; $email = "laowang@example.com"; $pre->bindParam ( ":name", $name ); $pre->bindParam ( ":pwd", $pwd ); $pre->bindParam ( ":email", $email ); $pre->execute(); $name = "柴科夫斯基"; $pre->execute(array(":name"=>$name,":pwd"=>"love",":email"=>"abc@abc.com")); $pdo = null; } catch ( PDOException $e ) { echo "PDO连接MySQL数据库服务器失败"; die(); }?>

PHP操作MySQL-其他「程序员培养之路第四十九天」

PHP操作MySQL-访问数据库「程序员培养之路第四十八天」

PHP操作MySQL-介绍和配置「程序员培养之路第四十七天」

展开
收起

大数据实战:10G数据文件Hadoop和PHP多久能分析出结果?

对于很多用户来说10G数据可能并不大,对这个数量级的数据分析能算得上是大数据吗?

当然算了,我们只是拿这个10G的数据作为一个例子,系统能处理10G的数据,理论上就能处理100G甚至是1T数据。这要看咱们的硬件配置情况和所需要耗费的时间。假如1T数据1台服务器需要5小时才能出结果,那我们用60台服务器去并行计算,可能2分钟结果就能出来了。

本文假设你已经查看过我的Hadoop大数据规划以及安装配置的文章,已经安装并配置好PHP软件,安装并配置好Rsync软件。

PHP还能进行大数据计算呢?

当然能了。

Hadoop本身是Java写的,所以顺理成章的,给Hadoop写MapReduce,人们会自然地想到Java。但Hadoop里面有个Contrib叫做Hadoop Streaming,这是一个小工具,为Hadoop提供Streaming支持。利用该Streaming提供的API,允许用户使用任何语言编写Map函数和Reduce函数。因此,PHP也可以借助该API来进行大数据计算与分析。

另外这里面牵涉到下面这个问题。

MapReduce是什么?

概念“Map(映射)”和“Reduce(归约)”,是它的主要思想,它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。

从网上一搜就能搜到非常多的关于MapReduce的内容,写的都很好。但是不是很好理解。我根据我的理解直白的说明如下,欢迎拍砖:

1、一个超大数据文件(超过1T)切成6份(我们有6个DateNode),分别存到6台服务器上;

2、我们的计算程序分别在这6台服务器上计算自己的那份,得出结果,过程中可能会把自己的那份切成更小的份数(Hadoop默认一份为128M);

3、6台服务器计算的结果再汇总到一个服务器上,进行汇总计算,得出最终结果。

以上例子“把数据分到6台服务器并计算出结果”就是对Map(映射)最直白的其中一种解释;而“6台服务器计算结果汇总到一起,得出最终结果”就是对Reduce(归约)最直白的其中一种解释。

这么一看,是不是就没什么神秘的了呢?

准备一个10G的数据文件

手头不容易找到10G那么大的文本文件,那咱就自己创造一个。随便打开一个英文网站,比如Firewalld的官网blog页面:

页面内全选(Ctrl+A),复制(Ctrl+C),然后打开CentOS Linux 8的SSH客户端。

新建一个文件名问10G.txt的文件,然后把刚才复制的内容粘贴进去,命令如下:

vi 10G.txt

然后就是不断的去找英文的内容,粘贴进去,感觉差不多了,进行下一步。

因为我们不可能一直复制出10G的文字那么多,那我们就利用CentOS Linux 8,自己复制自己,最终得出这么多内容,命令如下:

cat 10G.txt >> 11G.txt

cat 11G.txt >> 10G.txt

不断的重复这个过程,因为每次都翻倍,文件大小呈现指数级增长,很快我们就能得到一个10G的文件了。文件大小超过500M之后,会变的有点慢,有耐心的等一下。

将10G.txt上传至Hadoop的分布式存储系统HDFS,执行以下命令:

查看HDFS上的根目录:

hdfs dfs -ls /

在HDFS的根目录下简历input目录:

hdfs dfs -mkdir /input

查看input目录是否创建成功:

hdfs dfs -ls /

将10G.txt上传至HDFS的/input目录下:

hdfs dfs -put 10G.txt /input

查看10G.txt上传至/input目录是否成功:

hdfs dfs -ls /input

根据咱们设定的规则,HDFS会保存3个副本。也就是说咱们虽然上传了10G数据,但是HDFS会在整个系统上存储30G的数据。从上图最后一行的数据也能看的出来,第一个9.6G是咱们上传的数据量,后面的28.9G是HDFS实际存储的量。

WEB查看一下,每台服务器上存储了大约5G的数据,6台DataNode正好大约是30G(见上图)。

上传这10G文件的时候服务器的压力还是比较大的。CPU经常在75%徘徊,64G内存已经用去将近60G,磁盘的压力也很大。从截图中也能看到,上传开始时间“22:52:54”,上传结束时间“22:59:12”,花费了6分18秒的时间。这就是用一台服务器来模拟8台服务器的弱点。如果是真正的8台服务器,哪怕就是普通的PC安装的Linux系统搭建的服务器,只要装上万兆(10G)的网卡,再来个10块硬盘组Raid0,时间估计能压缩到1分钟以内。因为Hadoop技术上允许一部分DataNode掉线后系统正常运行,所以可以组Raid0提供存储服务来提高系统运行性能。

至此,这个10G的txt文件已经顺利的上传到了Hadoop的分布式存储服务HDFS上。

如果你还有多个文件要一起分析,都传到这个/input目录下即可。也就是说后面的分析程序是支持多个文件合并进行数据分析的,你不用自己手动把这几个文件合并到一个文件里面。

准备PHP数据分析程序

在集群的每台机器上安装PHP,并保持目录结构和配置文件一致,参考我的在CentOS Linux 8 上安装PHP的文章。并且已经安装并配置好了Rsync。

本文假定你已经做好了上述安装,如果没有做好,可以查看相关参考资料。

根据咱们的集群规划,主Rsync位于Hadoop222服务器,所以以下的程序编写部分我们在Hadoop222(192.168.1.222)上面操作。

编写Mapper程序

用root执行以下命令,配置好Hadoop用的PHP目录

mkdir -p /wwwroot/hadoop

chown -R hadoop:hadoop /wwwroot/hadoop

转为Hadoop用户执行以下操作:

su hadoop

vi /wwwroot/hadoop/mapper.php

输入以下内容:

#!/usr/bin/php

<?php

ini_set('memory_limit', '-1'); //内存使用不做限制,限制内存的事情交给系统自己解决

$word2count = array();

//STDIN (标准输入) = fopen(“php://stdin”, “r”);

//一行一行的读入数据

while (($line = fgets(STDIN)) !== false)

{

//删除前后的空格,字符转为小写

$line = strtolower(trim($line));

//“\W匹配:任意个非单词字符”

//通过“非单词字符”分割句子为“单词字符”

// PREG_SPLIT_NO_EMPTY返回分隔后的非空部分

$words = preg_split('/\W/', $line, 0, PREG_SPLIT_NO_EMPTY);

//单词计数增加

foreach ($words as $word)

{

if(!isset($word2count[$word]))

{

$word2count[$word] = 0;

}

$word2count[$word] += 1;

}

}

//输出结果到STDOUT(标准输出)

//我们这里的输出就是Reduce的输入

//即:reducer .php的输入

foreach ($word2count as $word => $count)

{

// PHP_EOL:换行符号,unix系列输出\n,windows系列输出\r\n,mac用输出\r

// chr(9):制表符分隔tab-delimited

echo $word, chr(9), $count, PHP_EOL;

}

这段代码的大致意思是:把输入的每行文本中的单词找出来,并以:

zoo 1

hello 3

world 5

这样的形式输出出来。

编写Reducer程序

用Hadoop用户执行以下操作:

su hadoop

vi /wwwroot/hadoop/reducer.php

输入以下内容:

#!/usr/bin/php

<?php

ini_set('memory_limit', '-1'); //内存使用不做限制,限制内存的事情交给系统自己解决

$word2count = array();

//STDIN (标准输入) = fopen(“php://stdin”, “r”);

//一行一行的读入数据

while (($line = fgets(STDIN)) !== false) {

//删除两头的空格

$line = trim($line);

//分析我们从mapper.php获得的输入

list($word, $count) = explode(chr(9), $line);

//将count(当前为字符串)转换为int

$count = intval($count);

//计算单词的数量总和

if ($count > 0) $word2count[$word] += $count;

}

//按词汇分类sort the words lexigraphically

//这个集合不是必需的,我们这样做只是为了

//使我们的最终输出看起来更像官方的Hadoop单词计数示例

// ksort() 函数对关联数组按照键名进行升序排序。

ksort($word2count);

//输出结果到STDOUT(标准输出)

foreach ($word2count as $word => $count)

{

echo $word, chr(9), $count, PHP_EOL;

}

这段代码的大意是汇总各Mapper的统计结果,最终得出每个单词出现了多少次数,排序后以:

hello 2

world 1

zoo 5

这样的形式输出,接受的输入方式“hello 1”,也就是mapper.php输出的方式。

给Mapper和Reducer赋予可执行权限。

chmod +x /wwwroot/hadoop/mapper.php /wwwroot/hadoop/reducer.php

执行PHP的MapReduce进行大数据分析

上面已经完成数据上传,代码的编写。我们要在每台服务器上查看一下,是否已经将PHP代码同步到每一台服务器上了。

在每台服务器上都执行以下命令:

ll /wwwroot/hadoop/

必须保证每台服务器上都有上述的两个PHP文件,才能执行以下大数据计算的命令:

hadoop jar /home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-3.2.1.jar -mapper /wwwroot/hadoop/mapper.php -reducer /wwwroot/hadoop/reducer.php -input /input/* -output /output

由于数据量比较大,所以数据计算的执行时间会比较长,需要耐心等待。

从服务器上的截图可以看到,服务器已经拿出100%的CPU资源,几乎100%的内存资源,每块硬盘轮流100%的资源,来完成咱们的大数据计算任务。

系统计算完毕之后,查看一下输出的结果,咱们设定的输出目录是HDFS的/output:

hdfs dfs -du -h /output

把输出结果下载下来查看:

hdfs dfs -get /output/part-00000

当然也可以在线查看,不过感觉不太方便,执行下述命令:

hdfs dfs -cat /output/part-00000

或者这个命令:

hdfs dfs -tail -f /output/part-00000

从上面的截图中可以看到,为了分析这10G的数据,程序执行的开始时间是“23:26:23”,程序执行的结束时间是“23:37:28”,共花费了11分5秒。

上述得到的结果是:字符串“0”在文件中出现了“36366795”次,字符串“00”在文件中出现了“105411”次,依次类推,整个计算结果的文件part-00000大小是30.9K。

总结

通过以上测试可以发现,用PHP做大数据分析真的非常容易。由于Hadoop提供了MapReduce接口,我们在编写PHP程序的时候,只需要关注逻辑处理即可,分片计算的部分Hadoop帮我们搞定了。

我们使用了一台服务器虚拟成8台服务器,对10G的数据进行分析,花费了11分5秒的时间。这个时间长度在可接受的范围之内,但如果做成多台真实的服务器进行计算,时间肯定会大幅缩减。如果有条件的时候,还真想试试。

展开
收起