thinkphp笔记-验证码、分页功能、图像处理

9614次阅读 931人点赞 作者: WuBin 发布时间: 2024-06-26 08:16:41
扫码到手机查看

验证码功能

https://www.bilibili.com/video/BV12E411y7u8?p=74&vd_source=1f21d9ebff6d1276c8c078b52f10b41d

验证码功能不是系统内置的功能了,需要通过composer 引入进来;

composer require topthink/think-captcha //开启session 方可使用
2024-6-26,版本是3.0.9

安装完成后,会发现config/captcha.php文件。而安装好的部分在vendor/topthink/think-captcha中。

新建一个controller/Code.php控制器

namespace app\controller;
use think\facade\View;

class Code
{
    public function form()
    {
        return View::fetch('form');
    }
}
在app/view/code/form.html中,直接使用验证码插件。
 <!-- 作为一个图片直接引入,且每次点击,图片都会改变,且验证码会自动写入session 用于对比验证 -->
    {:captcha_img()}

    <!-- 作为一个链接,Img标签要自己写,但是这次点击刷新需要自己手动写 -->
    <img src="{:captcha_src()}" alt="">

在html模板中

 <!-- 作为一个图片直接引入,且每次点击,图片都会改变,且验证码会自动写入session 用于对比验证 -->
    {:captcha_img()}

    <form action="../code/check" method="post">
        <input type="text" name="code">
        <input type="submit" value="验证">
    </form>

书写一个check方法

use think\facade\Validate;
use think\facade\View;
public function check()
 {
        $validate = Validate::rule([
            // 验证需要使用一个隐藏字段(在安装插件后就会有了)
            // captcha验证规则是内置的
            'captcha' => 'require|captcha'
        ]);

        // 和表单数据对比
        $result = $validate->check([
            'captcha' => input('post.code') // 是input框的name属性指向
        ]);

        dump($result);
}
验证码结果不区分大小写

如果要输出验证错误信息

if(!$result) {
            $validate->getError();
}

也可以使用助手函数直接进行判断验证;(其实就是将上面的一大段,都整合进一个函数中了)

if(!captcha_check(input('post.code'))) {
            echo '验证失败';
 }

验证码的所有配置参数如下,根据需要进行调用(在config/captcha.php中修改配置):

配置文件在config/captcha.php 中,直接进行参数配置即可;

参数描述默认
codeSet验证码字符集合
expire验证码过期时间(s)1800
math使用算术验证码false
useZh使用中文验证码false
zhSet中文验证码字符串
useImgBg使用背景图片false
fontSize验证码字体大小(px)25
useCurve是否画混淆曲线true
useNoise是否添加杂点true
imageH验证码图片高度,设置为0为自动计算0
imageW验证码图片宽度,设置为0为自动计算0
length验证码位数5
fontttf验证码字体,不设置是随机获取
bg背景颜色[243, 251, 254]
reset验证成功后是否重置true

上面的配置是全局配置,配置后全局生效,如果要单独生成一个验证器。

use think\captcha\facade\Captcha;

public function verify()
{
        return Captcha::create();
}
如此,访问tp6/public/code/verify,就会直接看到一张验证码的图片。然后在个别地方直接引入这个图片的链接即可!

上面的Captcha::create()依然使用的是全局配置,如果要针对某个验证码进行单独配置,需要在config/captcha.php中

return [
    //验证码位数
    'length'   => 3,
    // 验证码字符集合
    'codeSet'  => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
    // 验证码过期时间
    'expire'   => 1800,
    // 是否使用中文验证码
    'useZh'    => false,
    // 是否使用算术验证码
    'math'     => false,
    // 是否使用背景图
    'useImgBg' => false,
    //验证码字符大小
    'fontSize' => 50,
    // 是否使用混淆曲线
    'useCurve' => true,
    //是否添加杂点
    'useNoise' => true,
    // 验证码字体 不设置则随机
    'fontttf'  => '',
    //背景颜色
    'bg'       => [243, 251, 254],
    // 验证码图片高度
    'imageH'   => 0,
    // 验证码图片宽度
    'imageW'   => 0,
    // 默认下面是被注释的部分,需要额外的解开
    // 添加额外的验证码设置 
    'verify' => [
        'length' => 6,
        'useZh'  => true
    ],
];

额外的配置项与全局配置项属性一致,且与全局配置不冲突。当注册了额外的配置项,在控制器中:

use think\captcha\facade\Captcha;
public function verify()
 {
        return Captcha::create('verify');
 }

直接在create函数中传入即可。

分页功能

先构建基本的控制器和模板

controller/Page.php控制器

namespace app\controller;

use think\facade\View;
use app\model\User;

class Page
{
    public function index()
    {
        return View::fetch('index', [
            'list' => User::select()
        ]);
    }
}

app/view/page/index.html 模板

<table border="1">
    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>性别</th>
        <th>邮箱</th>
        <th>价格</th>
    </tr>
    {volist name='list' id='user'}
    <tr>
        <td>{$user.id}</td>
        <td>{$user.username}</td>
        <td>{$user.gender}</td>
        <td>{$user.email}</td>
        <td>{$user.price}</td>
    </tr>
    {/volist}
</table>

不管是数据库操作还是模型操作,都使用paginate()方法来实现;

namespace app\controller;

use think\facade\View;
use app\model\User;

class Page
{
    public function index()
    {
        // 每页显示5条 paginate直接使用 与select方法类似
        $list = User::paginate(5);

        return View::fetch('index', [
            'list' => $list
        ]);
    }
}

分页功能还提供了一个固定方式,实现分页按钮,只需要设置相应的CSS 即可;

<table border="1">
    {volist name='list' id='user'}
   ....
    {/volist}
</table>

{$list|raw} 
{$list|raw} 就是默认直接添加分页的按钮,但是没有样式,需要手动添加样式。

我们可以通过数组来传递多个参数,具体分页参数如下:

参数描述
list_rows每页数量
page当前页
pathurl路径
queryurl额外参数
fragmenturl瞄点
var_page分页变量
// 每页显示5条
        // $list = User::paginate(5);

        // 通过数组传参 可以传递更多参数
        $list = User::paginate([
            // 每页显示的行数 每页显示4条
            'list_rows' => 4,
            // 修改后tp6/public/page?abc=1 
            'var_page' => 'abc' // 默认是page
        ]);

        return View::fetch('index', [
            'list' => $list
        ]);

可以单独赋值分页的模版的HTML

$pageHtml = $list->render();

模板中使用 {$page|raw}

单独获取到总记录数量等

$list = User::paginate([
    // 每页显示的行数 每页显示4条
    'list_rows' => 4
]);

// 总共多少条
echo $list->total();
// 每页显示的条数
echo $list->count();
// 最后一页的页码
echo $list->lastpage();
// 分页的HTML
$pageHTML = $list->render();

return View::fetch('index', [
    'list' => $list,
    'pageHTML' => $pageHTML
]);

在模板中 使用获取的分页HTML
{$pageHTML|raw}

也可以设置分页的页码为简洁分页,就是没有1,2,3,4 这种,只有上下页;

$list = User::paginate(5, true);

如果你使用模型方式分页,则可以通过获取器修改每个字段的值,而分页本身也可以;

$list = User::paginate(5)->each(function($item) {
    $item['gender'] = "【{$item['gender']}】";
    return $item;
});

图像处理

图像处理功能不是系统内置的功能了,需要通过composer 引入进来;

composer require topthink/think-image

安装好后,插件会存在vendor/topthink/think-image中

引入进来之后,首先创建图像处理对象;获得了图像处理对象后,可以得到这张图片的各种属性;

namespace app\controller;
use think\Image;

class Picture
{
    public function index()
    {
        // 引入public目录下的image.jpg图片
        $image = Image::open('image.jpg');

        //图片宽度
        echo $image->width();
        //图片高度
        echo $image->height();
        //图片类型
        echo $image->type();
        //图片mime
        echo $image->mime();
        //图片大小
        dump($image->size());
    }
}

使用crop()方法可以裁剪图片,并使用save()方法保存到指定路径;

// 裁剪 (save没写路径默认在public目录里)
$image->crop(550, 400)->save('crop1.jpg');

将图片剪裁为500 * 400的图片,保存在public目录中。还有更多的参数。可以点击追踪方法内部,参看源码参数,了解更多的传值方法;

使用thumb()方法,可以生成缩略图,配合save()把缩略图保存下来;

// 缩略图
$image->thumb(500, 500)->save('1.png');
这里要注意一个问题,虽然设置了宽和高,但高度变成了282,说明是等比例的;可以点击追踪方法内部,第三个参数默认为:$type = self::THUMB_SCALING;

更多的常量参数

const THUMB_SCALING   = 1; //常量,标识缩略图等比例缩放类型
const THUMB_FILLED    = 2; //常量,标识缩略图缩放后填充类型
const THUMB_CENTER    = 3; //常量,标识缩略图居中裁剪类型
const THUMB_NORTHWEST = 4; //常量,标识缩略图左上角裁剪类型
const THUMB_SOUTHEAST = 5; //常量,标识缩略图右下角裁剪类型
const THUMB_FIXED     = 6; //常量,标识缩略图固定尺寸缩放类型
// 补全填充 (原图为横幅 则宽100同时 上下两侧留白边)
$image->thumb(500, 500, 2)->save('1.png');
// 按照高度500放大图片 填充满画布
$image->thumb(500, 500, 3)->save('1.png');

使用rotate()方法,可以旋转图片,默认是90 度,参数可以设置;

 // 旋转图片 (180度旋转)
$image->rotate(180)->save('1.jpg');

save()方法可以配置的参数除了保存文件名的路径,还有以下几个:

save('路径',['类型','质量','是否隔行扫描']),追踪到方法查看;

save($pathname, $type = null, $quality = 80, $interlace = true)
$interlace隔行扫描是与图片渲染时候效果有关,1是由模糊逐渐变清晰;2是直接出来的时候就是清晰,设置为true那么就是控制保存后的图片渲染时候是由模糊逐渐变清晰的。

water()方法,可以给图片增加一个图片水印,默认位置为右下角,可看源码常量;

 // 图片水印 (默认在右下角)
$image->water('watermark.png')->save('water1.jpg');
// 水印在左上角
$image->water('watermark.png', 1)->save('water1.jpg');
 /* 水印相关常量定义 */
    const WATER_NORTHWEST = 1; //常量,标识左上角水印
    const WATER_NORTH     = 2; //常量,标识上居中水印
    const WATER_NORTHEAST = 3; //常量,标识右上角水印
    const WATER_WEST      = 4; //常量,标识左居中水印
    const WATER_CENTER    = 5; //常量,标识居中水印
    const WATER_EAST      = 6; //常量,标识右居中水印
    const WATER_SOUTHWEST = 7; //常量,标识左下角水印
    const WATER_SOUTH     = 8; //常量,标识下居中水印
    const WATER_SOUTHEAST = 9; //常量,标识右下角水印

text()方法,可以给图片增加一个文字水印

先来看一个PHP原生函数 十分有用

// PHP原生函数 得到当前文件的位置 会输出D:\phpstudy\phpstudy_pro\WWW\xuexi\tp6\public
        echo getcwd();

因为PHP在使用字体时候,必须要指定磁盘的绝对路径,不能仅仅使用字符串!

// 文字水印 错的!!
        // $image->text('wubin', 
        //              'water-mark-font.ttf',  错!!
        //              30,
        //              '#fff'
        // )->save('text1.png');

以下是正确的方式

 $image->text('wubin', getcwd().'\water-mark-font.ttf', 20, '#ffffff')->save('text1.png');
注意,\water-mark-font.ttf 因win系统与其他系统不同会有差异,win下\代表路径分隔,其他系统应该是/

以下是完整测试代码

<?php
namespace app\controller;
use think\Image;

class Picture
{
    public function index()
    {
        // 引入public目录下的image.jpg图片
        $image = Image::open('image.jpg');

        //图片宽度
        echo $image->width();
        //图片高度
        echo $image->height();
        //图片类型
        echo $image->type();
        //图片mime
        echo $image->mime();
        //图片大小
        dump($image->size());

        // 裁剪 (save没写路径默认在public目录里)
        $image->crop(550, 400)->save('crop1.jpg');

        // 缩略图
        // 补全填充 (原图为横幅 则宽100同时 上下两侧留白边)
        $image->thumb(500, 500, 2)->save('1.png');
        // 按照高度500放大图片 填充满画布
        $image->thumb(500, 500, 3)->save('1.png');

        // 旋转图片 (180度旋转)
        $image->rotate(180)->save('1.jpg');

        // 图片水印 (默认在右下角)
        $image->water('watermark.png')->save('water1.jpg');
        // 水印在左上角
        $image->water('watermark.png', 1)->save('water1.jpg');

        // PHP原生函数 得到当前文件的位置 会输出D:\phpstudy\phpstudy_pro\WWW\xuexi\tp6\public
        echo getcwd();

        // 文字水印
        $image->text('wubin', getcwd().'\water-mark-font.ttf', 20, '#ffffff')->save('text1.png');

    }
}
点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:thinkphp
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9603次阅读 623人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    4297次阅读 317人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14452次阅读 948人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    13497次阅读 491人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    12015次阅读 963人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    16376次阅读 1307人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    15187次阅读 1234人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    29849次阅读 2347人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    25909次阅读 1994人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录