前言
Facade 也是一种设计模式,中文称为:外观模式,实际意义是:对复杂的接口进行一次包装,使其更容易使用。在实际开发中,能够帮助我们提高代码的简洁性、接口的易用性,以及更简单有效的测试途径。
如何使用它?
目前主流的几个框架:ThinkPHP5.1、Laravel、yii 都有它的影子(其他框架可能也有,未关注)。ThinkPHP5.1起开始提供Facade,但实现的比较简单,用官方的话说:降低上手门槛,让框架易用,是他们一贯的原则。
如果你基于上述几个框架,那么恭喜你,可以跟着框架文档学习使用即可。
Facade 的代码结构
图片为转载,来自CSDN。
又见“中间商”模式
经常看我文章的同学应该能注意到,这又是“中间商”模式。在应用程序和接口中间加了一层,就是:facade。在实际开发的过程中,我们会频繁利用“中间商”来解决问题,比如多层控制器、中间件等等。
中间商类的设计模式,具备普遍的优缺点:
优点,通过中间商来统一、简化代码行为缺点,增加代码的架构复杂度(还会稍稍降低执行效率)Facade 实现原理
接下来是给大家写的演示代码。
代码解析
Facade类
此为外观模式的管理类,负责外观模式的运转。如果你使用框架,这个类都是框架预先写好的。
App
实际想调用的目标类,我只实现了一个非静态方法:get,App::get() 这样的调用会报错。 实际开发中,所有的业务代码都写在这里。
AppFacade
App的外观类,它继承自 Facade,里边有一个方法 getFacadeAccessor(),负责指向到目标类。
使用
我们可以通过 AppFacade::get() 这样的语法,就能执行App类的get()方法,效果是一样的。
重点是:用静态语法调用了非静态方法,这也是 PHP中 Facade 模式的显著特点。
总结
就算你不知道它有什么用,但至少语法简单了,对吧。
对于很多用户来说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秒的时间。这个时间长度在可接受的范围之内,但如果做成多台真实的服务器进行计算,时间肯定会大幅缩减。如果有条件的时候,还真想试试。
前言
今天要说的是3个符号:\r\n\t,它们是编程中最常见的几个制表符。
简介
\r 表示回车
ASCII 码:13
“回车”是一个历史遗留问题,在机械打印机时代表示将打印头定位到左边。虽然,我们键盘上有回车键(enter),但是它和真正的回车其实是有区别的。
\n 表示换行
ASCII 码:10
这才是 enter 键应该干的事情。
\t 是水平制表符
ASCII 码:9
这个是 tab 键,在编程的时候默认缩进就是“\t”,不过现在主流是用4个空格来代替它。
回车和换行有什么区别?
在打字机时代,回车是将打印头定位到左边(你可以理解为复位)换行则是将打印头向下挪一行。
打字机每次换行必须是:回车+换行,才可以。
这和我们有什么关系?
没什么关系,历史遗留问题。
今天还有遗留问题吗?
windows 系统上,enter键,依然是 回车+换行的风格,也就是:\r\n
linux、mac系统上,enter键,则只是换行,也就是 \n(仅限macos 10以后的版本)
这会造成什么后果?
linux 上敲的文本(文档、代码等),在windows 上变成一行。
我试过了,并没有变成一行
因为你使用的是专业编辑器(他们帮我们做了自动转换),要用最传统的,比如:记事本。
对编程有什么影响?
在使用PHP fopen 函数时,就有这样的提示:
PS:极为少见的提醒了两次。
了解这些制表符,对编程有什么帮助?
还是以 PHP为例:
echo "test \n test" 这样可以实现换行(如果你想在HTML中实现换行,要用<br>)
echo 'test \n test' 这样则不行。(看出和上面的区别了吗?)
当你使用 trim() 函数时,它都做了什么?
很多人都知道PHP中有一个过滤首尾空格的函数,但其实除了空格它还做了更多,包括:
" " (ASCII 32 (0x20)),普通空白字符。"\t" (ASCII 9 (0x09)), 制表符."\n" (ASCII 10 (0x0A)),换行符。"\r" (ASCII 13 (0x0D)),回车符。"\0" (ASCII 0 (0x00)), NUL空字节符。"\x0B" (ASCII 11 (0x0B)),垂直制表符。
总结
制表符位于 ASCII 码的0-31位(除了制表符还有其他,统称为控制字符),在编程中处理字符串的时候,应该要小心这些东西。
小程序入局者越来越多,微信小程序第一个开发,相当于确立了非官方标准,之后的支付宝小程序俨然改了一个名字版的微信小程序存在,再到之后的百度智能小程序,开发框架及标准都是一样的。
一张图集齐bat小程序三家小程序除了三个文件,app.json,app.js,app.wxss,index.wxml叫法不同外,其他近乎一样
app.json 对应的是配置文件
app.js 三家一样的,都是javascript文件,前后端同学应该都懂
app.wxss 这个叫法不一样,但是都是css的超集[支持css的绝大部分语法,基本可以理解就是css]
index.wxml 这个就是对应就是网页三剑客的html了,只是有一些稍微的区别而已。
对于入门phper来讲,最简单也最高效的开发框架非tp(thinkphp)莫属了,为啥呢?有中文文档,国人开发,清晰的文档及国人高效论坛的支持。进化到thinkphp 5版本的tp以api接口为定义,更加符合现在小程序的开发逻辑, 也更贴合现在前端环境的MVVM架构。
在开发小程序环境下,对于传统的mvc架构,砍掉了v,只剩下mc。小程序端相当于v。
thinkphp5开发将主要着重于mc方面的开发
在接下来的课程中,我们将基于thinkphp5+wepy的方式讲解价值百万小程序商城的开发。
欢迎关注我门的百家号,持续更新小程序商城开发系列
前言
单例模式,是一种设计模式。而设计模式通常代表了“最佳设计”,是前人踩坑之后总结出来的经验精华,比如MVC也是一种设计模式。(关于设计模式可以写很长很长的一个系列,暂时不和大家多说)
什么是单例模式
核心是一个“单例”的类,所谓单例指的是:系统中永远“只存在一个实例对象”。无论你调用多少次,实例化多少次,永远都是同一个对象。
这样做有什么意义?
它最大的特点在于唯一,借此实现的最重要的功能是:“共享”。比如:在程序启动时,将配置信息赋值给类属性,后续执行时可随时取出配置信息。
演示代码
几乎每个框架里都有类似这样的一份代码。
总结
今天介绍的单例模式,其实就是借助了静态类属性的特性实现的。
ThinkPHP框架常用的是MVC模式,M是模型、V是视图,C是控制器。通过MVC模式将数据从数据库中查询出来,然后传递到页面中。下面我们来说一下具体的情况;
程序一、视图渲染
模板定位规则:当前模块/view/当前控制器名(小写)/当前操作(小写).html。在5.1.6版本后系统会以简洁模式定位模板文件位置,规则如下:当前模块/view/当前控制器(小写)_当前操作(小写).html
1、Fetch方法
fetch方式是渲染模板时最常用的方法,在使用此方法的前提是控制器类需要继承系统控制器基础类。使用方式如下:
(1)、不需要传递任何参数,框架会自动定位到模板文件;
return $this->fetch();
(2)、传递一个参数,框架会定位至当前控制器下的参数一模板文件;
return $this->fetch('edit');
(3)、传递两个参数,框架会定位至参数一控制器下的参数二模板文件;
return $this->fetch('member/read');
注意事项:在书写参数时请不要书写任何后缀,参数只是目录名称或文件名称而已。
(4)、视图根目录下文件
如果想把view文件夹内的单独文件进行渲染,可以在参数位置进行如下书写:
return $this->fetch('/menu');
(5)、特殊模板文件或特殊位置文件
如果项目中存在特殊模板文件,又不想移动位置,可以通过如下方式进行调用:
return $this->fetch('./template/menu.html');
上面书写的目录位置是相对于当前项目入口文件位置(public目录),模板文件后缀无固定要求,可以为html、php、tpl等格式
PHP代码2、助手函数方式
如果控制器未继承系统基础控制器类,同样可以实现视图模板的输出,框架提供了助手函数view(),可以使用如下命令:
return view();
可传递参数及数据,常见的使用方式如下:
return view('模板文件路径','数据');
3、直接解析模板方式
项目中某些页面可能通过直接解析模板的方式就可以实现功能,那么我们可以通过最简单的方式对模板文件进行输出。使用如下命令:
return $this->display();
此方式会直接渲染内容,同样模板标签在视图中可以正常使用。
HTML模板二、视图赋值
1、assign方法
在继承系统基础控制器类后可以通过如下命令进行视图赋值:
$this->assign("名","值");
批量赋值方式:
$this->assign(['名'=>'值','名'=>'值']);
2、方法传入参数方式
此方式在进行视图渲染中提及到了,通过设置模板文件位置时携带数据。命令如下:
$this->fetch('path',['名'=>'值','名'=>'值']);$this->display('path',['名'=>'值','名'=>'值']);
3、助手函数赋值方式
这种方式是项目开发过程中最常见的模式,助手函数无需继承基础控制类,相对而言代码更加精简、可读性更高。命令如下:
return view('path',['名'=>'值','名'=>'值']);
4、公共模板变量赋值方式
可以使用视图类的share静态方法进行全局公共模板变量赋值。命令如下:
use think\facade\View;// 赋值全局模板变量View::share('name','value');// 或者批量赋值View::share(['name1'=>'value','name2'=>'value2']);
视频过滤三、视图过滤
1、局部过滤
在单独方法内进行视图过滤操作。命令如下:
// 使用视图输出过滤return $this->filter(function($content){returnstr_replace("\r\n",'<br/>',$content);})->fetch();
2、全局过滤
如果进行全局过滤方式,需要在初始化方法中进行设置。命令如下:
protected functioninitialize(){$this->view->filter(function($content){returnstr_replace("\r\n",'<br/>',$content); });}
总结:视图过滤方式可以理解过对视图模板中内容进行了替换操作,可以通过此方式减少代码空行,无用的缩进。减少代码体积。
四、模板引擎
框架中内置了模板引擎,默认可以忽略对此进行设置,同时框架支持自定义引擎模式。在配置目录(config目录)下的template.php文件中可进行配置。
默认提供了两种扩展引擎:think-angular、twig(都不是很完美,不建议使用
4、)
五、扩展
如果只想获得解析文件而不进行渲染,如果生成静态HTML文件,采用纯静态化模式。可以使用如下命令:
$html = $this->fetch()->getContent();
此方式返回字符串,可以继承文件创建方式,批量生成HTML静态文件,便于网站优化。
六、总结
1、依据场景,选择不同的渲染方式;
2、合理的进行模板赋值;
3、牢记特殊模板文件位置是基础项目入口文件位置;
4、模板文件配置目录为:config/template.php文件;
在开发过程中,我们需要写控制器、模型、验证代码。最后要写模板代码,如果是前后端分离项目则不用写模板了。直接在接口中返回数据就可以了。模板代码包含了很多知识,下面举例介绍一下;
代码变量输出
1、常见的输出方式是使用大括号({ })的形式,里面写入变量名称。在runtime/temp目录下可以看到编译后的文件,括号解析成了<?php ?>的形式,并且里面包含htmlentities。命令如下(注意$ 和 { 之间不能存在空格):
{$data}
2、原样解析,如果解析富文本内容时使用,使用示例:
{$data|raw}
3、默认值,使用示例:
{$data|default='这是一个默认值'}
4、系统变量输出,主要是获取用户昵称,使用示例:
{$Think.session.name}
5、常量输出,使用示例:
{$Think.PHP_VERSION}
6、配置输出,主要是获取基础网址,使用示例:
{$Think.config.default_module}
PHP使用函数
1、框架内置规则:
2、应用方式:
2.1、单函数应用,使用示例:
{$data.name|md5}
2.2、多函数应用,使用示例:
{$name|md5|upper|substr=0,3}
互联网开发运算符
1、常见运算符
2、三元运算符
2.1、默认写法
{$status?'正常':'错误'}
2.2、简单写法,表示有则输出,无则输出默认值
{$name ??'默认值'}
2.3、为真写法,表示为真的时候才输出默认值
{$name?='默认值'}
2.3、真假写法、表示为真输出值,否则输出默认值
{$name ?:'NO'}
2.4、表达式写法,表达式为真则输出值一,否则输出值二
{$a==$b ?'yes':'no'}
程序代码原样输出
原样输出使用较少,如果想让输出内容不被模板标签所解析,使用如下命令进行输出:
{literal} Hello,{$name}!{/literal}
模板注释
模板注释和代码注释是两种方式,模板注释不会在页面上查看到被注释的代码,而代码注释则可以查看的到。使用方式如下:
{/* 这是模板注释内容*/} 或 {// 这是模板注释内容 }
模板布局
模板布局总结来说就两点:配置和模板;
配置分为模块配置和应用配置,一般情况下后台多应用模板布局方式,在后台模块config/template.php文件内(默认不存在,需手动创建)设置如下代码:
'layout_on'=>true, //开启布局模式'layout_name'=>'layout', //布局文件名称,可设置为 'index/layout'目录形式'layout_item'=>'{__REPLACE__}' //输出替换变量
模板继承
在实际项目开发过程中使用较少,主要是因为继承过于麻烦。
包含文件
在实际项目开发过程中,前端页面使用较多,使用方式较为单一;
1、使用模版文件,多个文件使用逗号分隔;
{include file="public/header,public/menu"/}
2、传入参数,此方式需注意模板中变量值必须存在;
{include file="Public/header" keywords="开源WEB开发框架"/}
开发代码输出替换
1、配置,在应用或模块配置目录下的template.php文件中进行如下代码配置:
'tpl_replace_string'=>['__STATIC__'=>'/static','__JS__'=>'/static/javascript',]
2、总结,优点:方便更改;但是不建议使用,建议在开发过程中设置好目录位置。
标签库
标签库类似于Java的Struts中的JSP标签库,每一个标签库是一个独立的标签库文件,标签库中的每一个标签完成某个功能,采用XML标签方式(包括开放标签和闭合标签)。具体内容请参考官方文档。
内置标签
1、普通循环标签,使用示例:
{volist name="list" id="vo" key="k"}{$k}.{$vo.name}{/volist}
如果没有指定key属性的话,默认使用循环变量i
2、控制输出行数,如输出其中的第5~15条记录,使用示例:
{volist name="list" id="vo" offset="5" length='10'}{$vo.name}{/volist}
3、比较标签(不常用)
4、SWITCH标签(不常用),使用示例:
{switch User.level} {case 1}value1{/case} {case 2}value2{/case} {default /}default {/switch}
5、资源文件加载(常用),使用实例:
{load href="/static/js/common.js,/static/css/style.css"/}
互联网标签扩展
此扩展在开发过程中并不常用,使用起来较为麻烦。
路由是开发过程中比较重要的一环,在ThinkPHP5.1版本后路由默认开启,并且不可以关闭,足以可见它的重要性。下面我们来具体的说一下;
注意事项
1、默认开启、不可关闭;
2、优先匹配、多模式支持;
3、匹配成功,不再继续匹配;
4、默认支持数字、字母、下划线,不支持中文及特殊符号;
PHP主要作用
1、URL链接更加规范、美观,更加适合SEO优化;
2、隐式传入额外请求参数;
3、请求方式拦截,区分GET、POST等请求方式;
4、绑定请求数据;
5、处理请求缓存,优化程序响应时间;
6、路由中间件支持(V5.1.6+版本以上支持);
SEO优化路由定义
1、定义位置:route/route.php文件内,可以在route目录内多文件定义,最终框架会进行路由整合,建议采用域名+分组模式定义路由。
2、定义方式:
Route::get('new/:id','News/read');// 定义GET请求路由规则Route::post('new/:id','News/update');// 定义POST请求路由规则Route::put('new/:id','News/update');// 定义PUT请求路由规则Route::delete('new/:id','News/delete');// 定义DELETE请求路由规则Route::any('new/:id','News/read');// 所有请求都支持的路由规则
请注意:
1、路由匹配成功后,原链接访问方式会失效;
2、完全匹配需在尾部添加$ ;
3、变量可有可无使用[] 包裹变量;
变量规则
系统默认的变量规则设置是\w+,只会匹配字母、数字和下划线字符,并不会匹配特殊符号和中文,需要定义变量规则或者调整默认变量规则。
1、局部配置(仅在当前路由有效)
*定义GET请求路由规则 并设置name变量规则
Route::get('new/:name','News/read')->pattern(['name'=>'\w+']);
2、全局配置(全部路由有效)
*设置name变量规则(采用正则定义)
Route::pattern('name','\w+');
*支持批量添加
Route::pattern(['name'=>'\w+','id'=>'\d+',]);
3、组合变量
*组合变量的优势是路由规则中没有固定的分隔符,可以随意组合需要的变量规则和分割符
Route::get('item-<name>-<id>','product/detail')->pattern(['name'=>'\w+','id'=>'\d+']);
PHP框架路由地址
闭包支持
实际开发过程中不常用,是一种简单直接的定义模式;
Route::rule('hello/:name',function(Request $request, $name){$method = $request->method();return'['. $method .'] Hello,'. $name;});
路由参数
互联网开发路由缓存
在定义大量的路由时,强烈建议使用路由缓存,注意仅在部署模式下有效,开启该缓存可以明显提升路由解析性能。
开启方式,在应用配置文件app.php中设置开启:
'route_check_cache'=>true,
开启后,会自动对每次的路由请求的调度进行缓存,第二次如果是相同的请求则无需再次经过路由解析,而是直接进行请求调度。
清除命令:
>php think clear --route
跨域请求
如果某个路由或者分组需要支持跨域请求,可以使用如下代码:
Route::get('new/:id','News/read')->ext('html')->allowCrossDomain();
注解路由
此方式不建议使用,缺点路由分散不方便管理,同时书写规则要求较为严格。
代码路由分组
强烈建议使用,下面书写一种比较完善的路由分组写法:
Route::group(['method'=>'get','ext'=>'html'],function(){Route::group('blog',function(){Route::rule('blog/:id','blog/read');Route::rule('blog/:name','blog/read');});})->pattern(['id'=>'\d+','name'=>'\w+']);
MISS路由
如果希望在没有匹配到所有的路由规则后执行一条设定的路由,可以注册一个单独的MISS路由,总结来说,可以应用于404页面,防止程序找不到路由而报错(一旦设置了MISS路由,相当于开启了强制路由模式);
Route::miss('public/miss');
资源路由
实际开发过程中不常用,不做描述。
快捷路由
此方式要求在控制器层面定义方法名称较为严格,简单做一下描述,不建议使用。
*给User控制器设置快捷路由
Route::controller('user','index/User');<?php namespace app\index\controller;class User{public functiongetInfo(){ }}
代码路由别名
路由别名不支持变量类型和路由条件判断,单纯只是为了缩短URL地址,并且在定义的时候需要注意避免和路由规则产生混淆。设置操作方法的请求类型:
*user 别名路由到 index/user 控制器
Route::alias('user','index/user',['ext'=>'html','allow'=>'index,save,delete','method'=>['index'=>'GET','save'=>'POST','delete'=>'DELETE'],]);
路由绑定
把当前的URL绑定到模块/控制器/操作,最多支持绑定到操作级别,例如在路由配置文件中添加:
*绑定当前的URL到 index模块
Route::bind('index');
*绑定当前的URL到 index模块的blog控制器
Route::bind('index/blog');
域名路由
支持完整域名、子域名和IP部署的路由和绑定功能,同时还可以起到简化URL、加快匹配的作用。
Route::domain(['blog','admin'],function(){Route::rule('new/:id','index/news/read');});
URL生成
支持路由URL地址的统一生成,并且支持所有的路由方式,但是不建议使用,直接在页面中手动设置,减少模板解析时间。
可以使用助手函数url,不需要继承框架基础控制器类即可使用,示例如下:
url('index/blog/read','id=5&name=thinkphp');
解析后为:/index.php/blog/5/name/thinkphp.html
其他配置方式不做过多讲解。请移步官方文档查看。
今天介绍一下网站里面常见的用户登录功能的实现
用户登录我们先想一想实现思路,先帮常用的代码放在一个include文件,里面放一些链接数据库,常用函数等公用文件。然后常用的用户信息修改。我们看看需要哪些页面
代码文件公用的头部文件和公用的底部文件单独放在一个页面,方便后期维护。然后就是登陆,注册,逻辑处理。
代码是最基础的实现原理。在原理掌握的基础长就可以进行深化,封装成class文件,简化代码和文件,我们先从最基础的实现原理来看看怎么实现。
登陆的界面首先是基本的登陆页面。不含css,后期可以把页面美化一下。
然后看看数据提交到了loginCheck.php页面进行哪些逻辑处理
php逻辑代码处理我们分析代码 显示引用配置文件,我们看看配置文件,也就是最基本的数据库信息,定义一个数组
数据库配置然后在看看mysql.fun.php通过文件名称我们可以知道这是一个操作数据库的代码,我们把一些常用的数据库操作方在这个里面。然后在去调用。
数据库链接操作注意@的用途,感兴趣的朋友去删除这个看看效果。
接着分析代码就是接受用户名和密码,执行查找数据库操作,存在这个记录就跳转到main.php页面,不存在就跳转到login.php页面。这样也就类似实现一个后台登陆管理功能的实现。登陆成功进入后台,登陆失败禁止登陆。原理是不是很简单。有兴趣的朋友快去制作一个登陆功能吧。
登陆后台模板小编收集了一下后台界面模板和登陆界面模板,想加强这方面的也去试试吧。
网站后台管理界面这样就实现了一个最基本的后台管理功能。
前言
工欲善其事,必先利其器。当你使用PHP编程,就需要对它的运行状况有所了解,否则事倍功半。
从今天起,和大家聊一聊 phpinfo() 函数所展示的信息含义。
phpinfo() 有什么用
它是一个系统函数,你可以直接编写代码 <?php phpinfo();?>,然后通过网页访问它,就能看到一个类似于这样的网页。
该网页包含了当前PHP的各种配置信息、扩展模块的信息等。以前有一种软件叫“探针”,专门用来探测服务器当前的PHP相关信息,现在随着虚拟主机的没落,已经越来越少人用啦。
如何阅读 phpinfo 的信息?
整个网页内容非常多,但主要分为四个部分
基本信息,也就是最顶部的内容。配置信息(Configuration)各种模块的信息PHP Credits,荣誉名单,记录对PHP语言有帮助的人PHP License 版权许可说明
基本配置
本文和大家说说基本信息中,各项内容的含义。(以我当前使用的PHP版本为例)
PHP 版本
最顶端:PHP Version 7.2.3,就是我们当前PHP的版本。
System
Darwin mac.local 17.5.0 Darwin Kernel Version 17.5.0: Fri Apr 13 19:32:32 PDT 2018; root:xnu-4570.51.2~1/RELEASE_X86_64 x86_64
运行此PHP的操作系统信息(我是mac机)
Build Date
Mar 19 2018 11:50:19
编译时间
Configure Command
'./configure' '--prefix=/usr/local/opt/php723' '--exec-prefix=/usr/local/opt/php723/' '--enable-debug' '--enable-fpm' '--with-iconv=/usr/' '--with-config-file-path=/usr/local/etc/php723' '--with-openssl=/usr/local/opt/openssl' '--enable-bcmath' '--with-curl' '--enable-exif' '--with-gd' '--with-mysqli' '--with-pdo-mysql' '--enable-zip' '--with-libzip' '--enable-mysqlnd' '--enable-sockets' '--enable-mbstring' '--enable-soap' '--with-freetype-dir=/usr/local/opt/freetype' '--with-xmlrpc' '--with-jpeg-dir=/usr/local/opt/jpeg' '--with-png-dir=/usr/local/opt/libpng' '--with-libxml-dir=/usr/local/opt/libxml2' '--without-gmp'
编译时,使用的各项配置信息。
Server API
FPM/FastCGI
当前采用的服务模式为 FCGI(快速通用网关接口协议),实现该协议的服务为 FPM(也就是PHP-FPM),与 NGINX 搭配的时候,基本都是通过它来进行通讯的,以后有机会和大家细聊。
Virtual Directory Support
disabled
虚拟目录支持,目前是禁用状态(disabled)也就是不支持。
Configuration File (php.ini) Path
/usr/local/etc/php723
PHP.ini 的所在目录。
Loaded Configuration File
/usr/local/etc/php723/php.ini
php.ini 所在的完整文件路径。
Scan this dir for additional .ini files
(none)
Additional .ini files parsed
(none)
PHP API
20170718
PHP核心版本,一般大版本变更时,此日期会随之变化(应该是核心版本的发布或编译日期)
其他
剩下的就不一一说明了,需要额外提醒的是,此处出现的 zend 是PHP解释器名字,你也可以认为它就是PHP核心,除此之外还有 zend框架、zend代码混淆、zend代码编辑器,注意不要把自己弄混了。
总结
今天先和大家介绍下基本信息,其中像PHP版本、configure的编译配置、php.ini的路径、php api 的版本等几项,是我们日常开发中需要用到的。其余的,大家有兴趣可以自己行了解。
明天开始,介绍第二部分:各种扩展库。