梦里 - 后端
type: channel
link: https://www.sunshine966.com/category/backend/
description: 后端
items: python 列表数组基本操作方法
items: PHP7.4版本下的excel表格导出应用案例
items: PHP根据经纬度计算两点距离与方圆范围方法
items: php redis 集合有序和无序的使用方法和应用场景
items: Yii2 的 components 是干什么的？底层原理是什么？
items: hyperf常用命令
items: 52 条 SQL 语句性能优化策略
items: Http通信协议
items: PHP Smarty模板技术
items: PHP 类封装文件上传

python 列表数组基本操作方法
type: item
date: 2025-12-04T11:44:18+08:00
description: 增 append（最后） insert(位置，内容)删 clear pop(2) remove("内容") del lis[2]改 list[0]= "ddd"查 index("") count list[]

PHP7.4版本下的excel表格导出应用案例
type: item
date: 2024-05-11T14:23:55+08:00
description: 最新版本的phpoffice组件最低版本要求PHP8.0，所以需要安装旧版本的，这里测试挑选了一个1.23的版本可以使用，在项目根目录composer运行安装组件：composer require phpoffice/phpspreadsheet:1.23应用案例：首先定义一个导出表格的函数#[NoReturn] function exportExcel($expTitle, $expCellName, $expTableData, $setWidth = []): void { $spreadsheet = new Spreadsheet(); $spreadsheet->getActiveSheet()->setTitle($expTitle . date('Ymd')); $cellNum = count($expCellName); $len = count($expTableData); // 设置表头字段 foreach ($expCellName as $k => $v) { $spreadsheet->getActiveSheet()->setCellValueByColumnAndRow($k + 1, 1, $v); } // 添加数据 foreach ($expTableData as $k => $v) { for ($i = 0; $i < $cellNum; $i++) { $spreadsheet->getActiveSheet()->setCellValueByColumnAndRow($i + 1, $k + 2, $expTableData[$k][$expCellName[$i]]); } } // // 添加所有边框/居中 // $styleArrayBody = [ // 'borders' => [ // 'allBorders' => [ // 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, // 'color' => ['argb' => '333333'], // ], // ], // 'alignment' => [ // 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, // ], // ]; // $total_rows = $len + 1; // 表格总行数要加上表头一栏 // $spreadsheet->getActiveSheet()->getStyle('A1:' . end($setWidth) . $total_rows)->applyFromArray($styleArrayBody); // // 设置列宽 // if ($setWidth) { // foreach ($setWidth as $k => $v) { // $spreadsheet->getActiveSheet()->getColumnDimension($v)->setAutoSize(true); // 列宽自定义 // } // } else { // $spreadsheet->getActiveSheet()->getDefaultColumnDimension()->setWidth(14); // } $filename = $expTitle . date('Ymd') . '.xlsx'; header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="' . $filename . '"'); header('Cache-Control: max-age=0'); $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output'); die(); }其次处理数据// 导出数据 $list = Db::table('user')->select(); $columns = [ 'id' => 'ID', 'username' => '用户名', 'age' => '年龄', 'gender' => '性别', ]; $columns_fields = array_keys($columns); // …

PHP根据经纬度计算两点距离与方圆范围方法
type: item
date: 2024-04-09T15:09:12+08:00
description: 经常遇到根据用户当前位置来计算出与用户之间的距离，或者给用户展示方圆一公里的店铺商家之类的功能。所以在此记录一下方法。/** * 求两个已知经纬度之间的距离,单位为米 * * @param lng1 $ ,lng2 经度 * @param lat1 $ ,lat2 纬度 * @return float 距离，单位米 */ function getdistance($lng1, $lat1, $lng2, $lat2) { // 将角度转为狐度 $radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度 $radLat2 = deg2rad($lat2); $radLng1 = deg2rad($lng1); $radLng2 = deg2rad($lng2); $a = $radLat1 - $radLat2; $b = $radLng1 - $radLng2; $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000; return $s; }根据经纬度获取指定方圆距离的四个点/** * 获取指定方圆距离的四个点 * param lng float 经度 * param lat float 纬度 * param distance float 该点所在圆的半径，该圆与此正方形内切，默认值为单位米 * return array 正方形的四个点的经纬度坐标 */ function getSquarePoint($lng, $lat,$distance) { $PI = 3.14159265; $longitude = $lng; $latitude = $lat; $degree = (24901*1609)/360.0; $raidusMile = $distance; $dpmLat = 1/$degree; $radiusLat = $dpmLat*$raidusMile; $minLat = $latitude - $radiusLat; //拿到最小纬度 $maxLat = $latitude + $radiusLat; //拿到最大纬度 $mpdLng = $degree*cos($latitude * ($PI/180)); $dpmLng = 1 / $mpdLng; $radiusLng = $dpmLng*$raidusMile; $minLng = $longitude - $radiusLng; //拿到最小经度 $maxLng = $longitude + $radiusLng; //拿到最大经度 $range = array( 'minLat' => $minLat, 'maxLat' => $maxLat, 'minLon' => $minLng, 'maxLon' => $maxLng ); return $range; }

php redis 集合有序和无序的使用方法和应用场景
type: item
date: 2024-04-05T16:08:24+08:00
description: 无序集合（Set）的使用方法和应用场景：使用方法：添加元素到集合：$redis->sAdd('myset', 'element1'); $redis->sAdd('myset', 'element2');获取集合中的所有元素：$elements = $redis->sMembers('myset');检查元素是否存在于集合中：$exists = $redis->sIsMember('myset', 'element1');从集合中移除元素：$redis->sRem('myset', 'element1');应用场景：用户标签：记录用户的兴趣、爱好等，方便进行个性化推荐或群体分析。好友列表：用于表示用户的好友关系，便于进行社交功能的实现。记录在线用户：用于快速查找当前在线的用户。去重：用于去重操作，保证数据的唯一性。有序集合（Sorted Set）的使用方法和应用场景：使用方法：添加元素到有序集合并指定分数： $redis->zAdd('mysortedset', 1, 'element1'); $redis->zAdd('mysortedset', 2, 'element2');获取有序集合中的成员数量：$size = $redis->zCard('mysortedset');获取成员的分数：$score = $redis->zScore('mysortedset', 'element1');获取指定范围内的成员：$members = $redis->zRange('mysortedset', 0, -1);应用场景：排行榜：记录用户积分、贡献值等，并根据分数进行排序。按分数范围查询：查询指定范围内的成员，如时间范围、价格范围等。记录点击量：用于统计网站的热门内容或广告的点击量。实时排名：用于实时显示排名变化，如股票排行、比赛排名等。总之，无序集合和有序集合各有自己适用的场景。无序集合适合简单的去重、集合运算等场景，而有序集合适合需要排序和范围查询的场景，如排行榜、实时统计等。

Yii2 的 components 是干什么的？底层原理是什么？
type: item
date: 2023-11-24T17:34:00+08:00
description: 在 Yii2 中，components 是用于配置和管理各种应用程序组件的关键部分。组件是 Yii2 框架中的基本构建块，可以是数据库连接、缓存、日志处理、邮件发送等。通过在配置文件中定义 components，我们可以在整个应用程序中轻松访问和使用这些组件。底层原理：组件的配置：在 Yii2 中，组件配置是以数组的形式定义在应用程序的配置文件中，通常是 config/web.php 或 config/console.php。配置文件可以定义多个组件，每个组件都有一个唯一的名称，用于在应用程序的其他部分引用和访问该组件。组件的实例化和注册：当应用程序启动时，Yii2 框架会根据配置文件中的组件定义，实例化并注册这些组件。这意味着当你访问应用程序的某个组件时，Yii2 会返回该组件的实例，并且这个实例将在整个应用程序的生命周期内保持不变，以确保组件的单例模式。组件的访问：要在 Yii2 应用程序中访问组件，可以使用 Yii::$app->componentName 的方式，其中 componentName 是在配置文件中定义的组件名称。通过这种方式，你可以在任何地方访问和使用组件的功能，而不需要重复实例化或管理组件的生命周期。组件的依赖注入：Yii2 框架还支持组件之间的依赖注入。这意味着你可以在定义一个组件时，通过 depends 属性指定该组件依赖于其他组件。这样，当实例化一个组件时，Yii2 会自动解析和注入该组件所依赖的其他组件，使组件之间的耦合度降低，代码更加灵活和可维护。示例：以下是一个简单的组件配置示例，演示了如何定义一个数据库连接组件和一个缓存组件：return [ 'components' => [ 'db' => [ // 数据库连接组件 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=mydatabase', 'username' => 'db_user', 'password' => 'db_password', 'charset' => 'utf8', ], 'cache' => [ // 缓存组件 'class' => 'yii\caching\FileCache', ], // 其他组件的配置... ], // 应用程序的其他配置... ];在上述示例中，我们定义了两个组件：db 是一个数据库连接组件，使用了 yii\db\Connection 类来表示数据库连接；cache 是一个缓存组件，使用了 yii\caching\FileCache 类来表示文件缓存。通过在代码中使用 Yii::$app->db 和 Yii::$app->cache，我们可以在整个应用程序中访问和使用这两个组件的功能。总结：components 是 Yii2 框架中用于配置和管理应用程序组件的关键部分，底层原理是通过配置文件中的数组定义来实例化和注册这些组件，并通过依赖注入实现组件之间的耦合。

hyperf常用命令
type: item
date: 2023-05-13T15:41:00+08:00
description: 查看已安装的swoole的版本php --ri swoole查看phpinfo信息php -r "phpinfo();" |grep swoole查看命令列表php bin/hyperf.php启动hyperf服务php bin/hyperf.php startphp bin/hyperf.php server:watch生成控制器php bin/hyperf.php gen:Controller UserControllerphp bin/hyperf.php gen:Controller --namespace='App\Application\Admin\Controller' UserController生成一个自定义命令php bin/hyperf.php gen:command FooCommand生成Modelphp bin/hyperf.php gen:model User生成监听器php bin/hyperf.php gen:listener RegisterListener生成表单验证器php bin/hyperf.php gen:request UserForm生成配置文件php bin/hyperf.php vendor:publish hyperf/view

52 条 SQL 语句性能优化策略
type: item
date: 2023-02-06T16:34:00+08:00
description: 1、对查询进行优化，应尽量避免全表扫描，首先应考虑在where及order by涉及的列上建立索引。2、应尽量避免在where子句中对字段进行null值判断，创建表时NULL是默认值，但大多数时候应该使用NOT NULL，或者使用一个特殊的值，如0，-1作为默认值。3、应尽量避免在where子句中使用!=或<>操作符，MySQL只有对以下操作符才使用索引：<，<=，=，>，>=，BETWEEN，IN，以及某些时候的LIKE。4、应尽量避免在where子句中使用or来连接条件，否则将导致引擎放弃使用索引而进行全表扫描，可以使用UNION合并查询：select id from t where num=10 union all select id from t where num=20。5、in和not in也要慎用，否则会导致全表扫描，对于连续的数值，能用between就不要用in了：Select id from t where num between 1 and 3。6、下面的查询也将导致全表扫描：select id from t where name like‘%abc%’或者select id from t where name like‘%abc’若要提高效率，可以考虑全文检索。而select id from t where name like‘abc%’才用到索引。7、如果在where子句中使用参数，也会导致全表扫描。8、应尽量避免在where子句中对字段进行表达式操作，应尽量避免在where子句中对字段进行函数操作。9、很多时候用exists代替in是一个好的选择：select num from a where num in(select num from b)。用下面的语句替换：select num from a where exists(select 1 from b where num=a.num)。10、索引固然可以提高相应的select的效率，但同时也降低了insert及update的效率，因为insert或update时有可能会重建索引，所以怎样建索引需要慎重考虑，视具体情况而定。一个表的索引数最好不要超过6个，若太多则应考虑一些不常使用到的列上建的索引是否有必要。11、应尽可能的避免更新clustered索引数据列， 因为clustered索引数据列的顺序就是表记录的物理存储顺序，一旦该列值改变将导致整个表记录的顺序的调整，会耗费相当大的资源。若应用系统需要频繁更新clustered索引数据列，那么需要考虑是否应将该索引建为clustered索引。12、尽量使用数字型字段，若只含数值信息的字段尽量不要设计为字符型，这会降低查询和连接的性能，并会增加存储开销。13、尽可能的使用varchar/nvarchar代替char/nchar，因为首先变长字段存储空间小，可以节省存储空间，其次对于查询来说，在一个相对较小的字段内搜索效率显然要高些。14、最好不要使用”“返回所有：select from t ，用具体的字段列表代替“*”，不要返回用不到的任何字段。15、尽量避免向客户端返回大数据量，若数据量过大，应该考虑相应需求是否合理。16、使用表的别名(Alias)：当在SQL语句中连接多个表时，请使用表的别名并把别名前缀于每个Column上。这样一来，就可以减少解析的时间并减少那些由Column歧义引起的语法错误。17、使用“临时表”暂存中间结果 ：简化SQL语句的重要方法就是采用临时表暂存中间结果，但是临时表的好处远远不止这些，将临时结果暂存在临时表，后面的查询就在tempdb中了，这可以避免程序中多次扫描主表，也大大减少了程序执行中“共享锁”阻塞“更新锁”，减少了阻塞，提高了并发性能。18、一些SQL查询语句应加上nolock，读、写是会相互阻塞的，为了提高并发性能，对于一些查询，可以加上nolock，这样读的时候可以允许写，但缺点是可能读到未提交的脏数据。使用nolock有3条原则：查询的结果用于“插、删、改”的不能加nolock；查询的表属于频繁发生页分裂的，慎用nolock ；使用临时表一样可以保存“数据前影”，起到类似Oracle的undo表空间的功能，能采用临时表提高并发性能的，不要用nolock。19、常见的简化规则如下：不要有超过5个以上的表连接（JOIN），考虑使用临时表或表变量存放中间结果。少用子查询，视图嵌套不要过深，一般视图嵌套不要超过2个为宜。20、将需要查询的结果预先计算好放在表中，查询的时候再Select。这在SQL7.0以前是最重要的手段，例如医院的住院费计算。21、用OR的字句可以分解成多个查询，并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关，如果查询需要用到…

Http通信协议
type: item
date: 2022-10-13T11:17:06+08:00
description: 第一章 前言我们现实生活中的协议是指相互遵守的规定，单方面违背，协议不成立；而在互联网交互的过程中，也存在这许多协议，例如FTP、HTTP、STMP、TCP/IP等。而HTTP协议则是web服务器和web客户端达成的一种可靠的数据传输协议，通过HTTP可以从遍布全世界的Web服务器上将JPEG图片，HTML页面，文本文件，MPEG电影，WAV音频文件和其他资源信息块迅速、便捷、可靠地搬移到人们桌面上的Web浏览器上去。它能够确保数据在传输的过程当中不会损坏或者产生混乱。这样，对用户来说是个好事，同样对internet应用的开发人员来说也是一件好事。因为我们在开发过程中也不需要担心自己的页面和数据会在传输过程中发生破坏和畸变了。第二章 WEB客户端和服务器Web内容都是存储在Web服务器上的。Web服务器所使用的是HTTP协议，因此经常会被称为HTTP服务器。这些HTTP服务器存储了因特网中的数据，如果HTTP客户端发出请求的话，它们会提供数据。客户端向服务器发送HTTP请求，服务器会在HTTP响应中回送所请求的数据。那么一次请求和响应的过程中发生了什么？HTTP属于无状态链接协议，即是限制每次连接只处理一个请求。服务器处理完客户的请求，并收到客户的应答后，即断开连接。采用这种方式可以节省传输时间和服务器资源。当然也有有状态链接，那就是我们常用的QQ。H5新增的特性中也包含Websocket帮助我们构建长链接。第三章 资源和媒体类型web服务器是web资源的宿主，而web资源就是我们常见的web内容的源头，最简单的web资源就是我们服务器中的静态文件：文本文件，HTML文档，JPEG图片文件，mp4文件等等。当然web资源也可以是动态生成的，类似搜索引擎生成的页面，qq空间的动态等，总之，所有类型的内容来源都是资源。因特网上有数千种不同类型的数据类型，HTTP在传输的过程中为每个传输的数据都打上了名为MIME类型的数据类型标签，描述并标记多媒体内容。web浏览器请求一个网站的时候往往会发布多个HTTP请求，比如我们在浏览一个具有丰富图片的的web页面的时候，浏览器会执行一次HTTP请求来获取描述页面布局的HTML，然后发布另外的请求来获取每个嵌入式的图片，这些图片甚至可能位于不同的服务器上。因此，一个web页面通常不是单个资源，而是一组资源的集合。web服务器会为所有的HTTP对象数据附加一个MIME类型，当浏览器从服务器中取回一个对象的时候，会查看相关的MIME类型。看看它是否知道应该如何处理这个对象。对象的类型写在响应的content-type头中；同样，请求的时候浏览器也会告知服务器请求数据类型。常见的MIME类型：HTML 格式的文本文档由 text/html 类型来标记。普通的 ASCII 文本文档由 text/plain 类型来标记。JPEG 格式的图片为 image/jpeg 类型。GIF 格式的图片为 image/gif 类型。以application开头的媒体格式类型：application/xhtml+xml ：XHTML格式application/xml ： XML数据格式application/atom+xml ：Atom XML聚合格式application/json ： JSON数据格式application/octet-stream ： 二进制流数据（如常见的文件下载）application/x-www-form-urlencoded ： 中默认的encType，form表单数据被编码为key/value格式发送到服务器（表单默认的提交数据的格式）multipart/form-data ： 需要在表单中进行文件上传使用的数据格式。当然还有很多类型，我们就不一一列举了。MIME 参考手册：http://www.w3school.com.cn/media/media_mimeref.asp第四章 URL统一资源定位符（Uniform Resource Locator）是资源标识符最常见的形式。URL描述了一台特定服务器上某资源的特定位置。它们可以明确说明如何从一个精确、固定的位置获取资源。互联网上的每个文件都有一个唯一的URL，它包含的信息指出文件的位置以及浏览器应该怎么处理它。大部分 URL 都遵循一种标准格式， 这种格式包含三个部分。URL 的第一部分被称为方案（scheme）， 说明了访问资源所使用的协议类型。 这部分通常就是 HTTP 协议（http://）。第二部分给出了服务器的因特网地址（比如，http://www.itheima.com）。其余部分指定了 Web 服务器上的某个资源（比如， /static/image/common/zixuelogo.png）。URL可以更为细致的进行划分…

PHP Smarty模板技术
type: item
date: 2022-10-12T10:54:54+08:00
description: 1.1 目标掌握Smarty模板技术的实际运用；掌握Smarty模板技术的基础配置；掌握常用的smarty内置函数应用；掌握模板变量的使用以及常见的保留变量的使用；了解smarty配置文件的使用规范；掌握Smarty中内置函数：if分支、foreach和section循环的使用掌握Smarty在类中引入实现子类便捷使用的方式1.4 Smarty简介1.4.1 Smarty的引入1、为了分工合作，模板页面中最好不要出现PHP的代码。2、需要将表现和内容相分离1.2.2 Smarty介绍1.5 自定义Smarty1.3.1 演化一:（smarty生成混编文件）在模板中不能出现PHP定界符，标准写法如下：1、html代码 {$title} 2、PHP代码<?php $title='锄禾'; require './1-demo.html';运行结果不能解析的原因是：PHP不能识别 { 和 }解决：将大括号替换成PHP的定界符代码实现<?php $title='锄禾'; $str=file_get_contents('./index.html'); $str=str_replace('{','<?php echo ',$str); //替换左大括号 $str=str_replace('}',';?>',$str); //替换右大括号 file_put_contents('./index.html.php', $str); //写入混编文件 require './index.html.php'; //包含混编文件运行1.3.2 演化二：（smarty封装）由于每个页面都要替换定界符，所以需要将替换定界符的代码封装起来由于封装在类中，所有访问的方法需要通过面向对象的方式来访问1、创建Smarty.class.php<?php class Smarty{ private $tpl_var=array(); //赋值 public function assign($k,$v){ $this->tpl_var[$k]=$v; } /* *作用：编译模板 *@param $tpl string 模板的路径 */ public function compile($tpl){ $com_file=$tpl.'.php'; //混编文件地址 $str=file_get_contents($tpl); $str=str_replace('{$','<?php echo $this->tpl_var[\'',$str); //替换左大括号 $str=str_replace('}','\'];?>',$str); //替换右大括号 file_put_contents($com_file, $str); //写入混编文件 require $com_file; //包含混编文件 } }2、在index.php<?php require './Smarty.class.php'; $smarty=new Smarty(); $smarty->assign('title','锄禾'); $smarty->compile('./index.html');小结：1、需要将外部的变量赋值到对象的内部2、要通过面向对象的方式访问1.3.3 演化三：（有条件的生成混编文件）混编文件存在并且是最新的就直接包含，否则就重新生成模板文件修改时间<混编文件修改时间 => 混编文件是最新的Smarty类中的代码编译代码如下<?php class Smarty{ private $tpl_var=array(); //赋值 public function assign($k,$v){ $this->tpl_var[$k]=$v; } /* *作用：编译模板 *@param $tpl string 模板的路径 */ public function compile($tpl){ $com_file=$tpl.'.php'; //混编文件地址 //文件存在，并且模板文件修改时间<混编文件修改时间 if(file_exists($com_file) && filemtime($tpl)<filemtime($com_file)) require $com_file; else{ $str=file_get_contents($tpl); $str=str_replace('{$','<?php echo $this->tpl_var[\'',$str); //替换左大括号 $str=str_replace('}','\'];?>',$str); //替换右大括号 file_put_contents($com_file, $str); //写入混编文件 require $com_file; //包含…

PHP 类封装文件上传
type: item
date: 2022-10-12T10:50:06+08:00
description: 1.1 目标更好的理解类的封装特性；理解代码根据业务和功能的分类管理思想；理解公共控制器的作用，掌握公共控制器的封装；掌握PHP面向对象中继承的核心应用；1.2 文件上传1.2.1 封装文件上传类1、在Lib目录下创建Upload.class.php<?php namespace Lib; class Upload{ private $path; //上传的路径 private $size; //上传的大小 private $type; //允许上传的类型 private $error; //保存错误信息 public function __construct($path,$size,$type) { $this->path=$path; $this->size=$size; $this->type=$type; } //返回错误信息 public function getError(){ return $this->error; } /* * 文件上传 * @param $files array $_FILES[] * @return bool|string 成功返回文件路径，失败返回false */ public function uploadOne($files){ if($this->checkError($files)){ //没有错误就上传 $foldername=date('Y-m-d'); //文件夹名称 $folderpath= $this->path.$foldername; //文件夹路径 if(!is_dir($folderpath)) mkdir($folderpath); $filename=uniqid('',true).strrchr($files['name'],'.');//文件名 $filepath="$folderpath/$filename"; //文件路径 if(move_uploaded_file($files['tmp_name'],$filepath)) return "{$foldername}/{$filename}"; else{ $this->error='上传失败 '; return false; } } return false; } //验证上传是否有误 private function checkError($files){ //1、验证错误号 if($files['error']!=0){ switch($files['error']) { case 1: $this->error='文件大小超过了php.ini中允许的最大值,最大值是：'.ini_get('upload_max_filesize'); return false; case 2: $this->error='文件大小超过了表单允许的最大值'; return false; case 3: $this->error='只有部分文件上传'; return false; case 4: $this->error='没有文件上传'; return false; case 6: $this->error='找不到临时文件'; return false; case 7: $this->error='文件写入失败'; return false; default: $this->error= '未知错误'; return false; } } //2、验证格式 $info=finfo_open(FILEINFO_MIME_TYPE); $mime=finfo_file($info,$files['tmp_name']); if(!in_array($mime, $this->type)){ $this->error='只能上传'.implode(',', $this->type).'格式'; return false; } //3、验证大小 if($files['size']> $this->size){ $this->error='文件大小不能超过'.number_format($this->size/1024,1).'K'; return false; } //4、验证是否是http上传 if(!is_uploaded_file($files['tmp_name'])){ $this->error='文件不是HTTP POST上传的 '; return false; } return true; } }1.2.2 封装缩略图类在Lib目录下创建Image.class.php<?php namespace Lib; class Image{ /* * 制作缩略图 * @param $src_path 源图的路…