php系统实战

PHP实战技巧(11)PHP中的静态知识:facade

前言

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数据文件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秒的时间。这个时间长度在可接受的范围之内,但如果做成多台真实的服务器进行计算,时间肯定会大幅缩减。如果有条件的时候,还真想试试。

展开
收起

PHP实战技巧(12)编程中的常见制表符

前言

今天要说的是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位(除了制表符还有其他,统称为控制字符),在编程中处理字符串的时候,应该要小心这些东西。

展开
收起

百万[小程序商城]开发实战系列之thinkphp5开发第一篇

小程序入局者越来越多,微信小程序第一个开发,相当于确立了非官方标准,之后的支付宝小程序俨然改了一个名字版的微信小程序存在,再到之后的百度智能小程序,开发框架及标准都是一样的。

一张图集齐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的方式讲解价值百万小程序商城的开发。

欢迎关注我门的百家号,持续更新小程序商城开发系列

展开
收起

PHP实战技巧(11)PHP中的静态知识:单例模式

前言

单例模式,是一种设计模式。而设计模式通常代表了“最佳设计”,是前人踩坑之后总结出来的经验精华,比如MVC也是一种设计模式。(关于设计模式可以写很长很长的一个系列,暂时不和大家多说)

什么是单例模式

核心是一个“单例”的类,所谓单例指的是:系统中永远“只存在一个实例对象”。无论你调用多少次,实例化多少次,永远都是同一个对象。

这样做有什么意义?

它最大的特点在于唯一,借此实现的最重要的功能是:“共享”。比如:在程序启动时,将配置信息赋值给类属性,后续执行时可随时取出配置信息。

演示代码

几乎每个框架里都有类似这样的一份代码。

总结

今天介绍的单例模式,其实就是借助了静态类属性的特性实现的。

展开
收起

ThinkPHP框架实战讲解-视图解读

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文件;

展开
收起

ThinkPHP框架实战讲解-模板解读

在开发过程中,我们需要写控制器、模型、验证代码。最后要写模板代码,如果是前后端分离项目则不用写模板了。直接在接口中返回数据就可以了。模板代码包含了很多知识,下面举例介绍一下;

代码

变量输出

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"/}

互联网

标签扩展

此扩展在开发过程中并不常用,使用起来较为麻烦。

展开
收起

ThinkPHP框架实战讲解-路由解读

路由是开发过程中比较重要的一环,在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

其他配置方式不做过多讲解。请移步官方文档查看。

展开
收起

php实战案例制作一个用户登录功能

今天介绍一下网站里面常见的用户登录功能的实现

用户登录

我们先想一想实现思路,先帮常用的代码放在一个include文件,里面放一些链接数据库,常用函数等公用文件。然后常用的用户信息修改。我们看看需要哪些页面

代码文件

公用的头部文件和公用的底部文件单独放在一个页面,方便后期维护。然后就是登陆,注册,逻辑处理。

代码是最基础的实现原理。在原理掌握的基础长就可以进行深化,封装成class文件,简化代码和文件,我们先从最基础的实现原理来看看怎么实现。

登陆的界面

首先是基本的登陆页面。不含css,后期可以把页面美化一下。

然后看看数据提交到了loginCheck.php页面进行哪些逻辑处理

php逻辑代码处理

我们分析代码 显示引用配置文件,我们看看配置文件,也就是最基本的数据库信息,定义一个数组

数据库配置

然后在看看mysql.fun.php通过文件名称我们可以知道这是一个操作数据库的代码,我们把一些常用的数据库操作方在这个里面。然后在去调用。

数据库链接操作

注意@的用途,感兴趣的朋友去删除这个看看效果。

接着分析代码就是接受用户名和密码,执行查找数据库操作,存在这个记录就跳转到main.php页面,不存在就跳转到login.php页面。这样也就类似实现一个后台登陆管理功能的实现。登陆成功进入后台,登陆失败禁止登陆。原理是不是很简单。有兴趣的朋友快去制作一个登陆功能吧。

登陆后台模板

小编收集了一下后台界面模板和登陆界面模板,想加强这方面的也去试试吧。

网站后台管理界面

这样就实现了一个最基本的后台管理功能。

展开
收起

PHP实战技巧(15)通过phpinfo()了解你的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 的版本等几项,是我们日常开发中需要用到的。其余的,大家有兴趣可以自己行了解。

明天开始,介绍第二部分:各种扩展库。

展开
收起