-- 创造无限可能

本文是使用htinkphp6 + 阿里大于发送短信的使用案例

在接口中使用到了”alibabacloud/sdk”: “^1.8” 的sdk,需要在此之前事先通过composer安装



/**
     * 发送短信
     * @param string $mobile 手机号码
     * @param array $templateParam 设置短信模板参数
     * @param string $templateCode 模板code
     * @return bool 是否发送成功
     */
    public function sendVerifySms($mobile, $templateParam, $templateCode)
    {
        try {
            //获取配置信息
            $config = [
                    'access_key_id' => 'xxx',
                    'access_key_secret' => 'xxxx',
                    'sign_name' => 'xx平台',
                    'template_code' => [
                        'verify' => 'xxx',
                    ]
                ];

            // 创建客户端
            AlibabaCloud::accessKeyClient($config['access_key_id'], $config['access_key_secret'])
                ->regionId('cn-hangzhou')
                ->asDefaultClient();


            //调用阿里云短信发送接口
            $result = AlibabaCloud::rpc()
                ->product('Dysmsapi')
                //可根据实际情况选择不同的服务地区
                ->regionId('cn-hangzhou')
                ->version('2017-05-25')
                ->action('SendSms')
                ->method('POST')
                ->host('dysmsapi.aliyuncs.com')
                ->options([
                    'query' => [
                        'RegionId' => 'cn-hangzhou',
                        'PhoneNumbers' => $mobile,
                        'SignName' => $config['sign_name'],
                        'TemplateCode' => $templateCode,
                        'TemplateParam' => json_encode($templateParam),
                    ],
                ])
                ->request();

            //判断短信发送状态
            if ($result->toArray()['Code'] == 'OK') {
                return true;
            } else {
                return false;
            }
        } catch (ClientException|ServerException $e) {
            return false;
        }
    }

问题

centos7 安装好php后,执行php报错

php: error while loading shared libraries: libonig.so.2: cannot open shared object file: No such file or directory

原因分析

1.该库不存在
2.库存在但是没有正确引用

解决过程

1.查询库确认库是否真实存在:find / -name '*libonig*'
2.库存在则把文件复制到/usr/lib64下,或者正确配置库文件
3.库文件不存在则yum install libonig

当前使用的php框架是fastadmin,nginx版本是1.20
问题描述:
在宝塔面板添加站点并设置thinkphp伪静态后,网站前台能正常打开(例如:www.xxx.com/index.php/article/info),但是后台无法打开(www.xxx.com/admin.php/index/login)

但是以为一直是伪静态问题,不支持pathinfo导致的,查询很多资料后发现是nginx的php.conf配置问题

(示例:比如我的nginx下目录目录BtSoft\nginx\conf\php)
找到nginx下的conf下的对应php.conf配置,将try_files $uri =404;注释掉(我用的php版本是php73)

保存后重启nginx即可

更新composer时报错:Root composer.json requires PHP extension ext-http * but it is missing from your system. Install or enable PHP’s http extension

错误原文:
Your lock file does not contain a compatible set of packages. Please run composer update.

Problem 1
Root composer.json requires PHP extension ext-http * but it is missing from your system. Install or enable PHP’s http extension.

To enable extensions, verify that they are enabled in your .ini files:
D:xxx\php\74\php.ini
You can also run php —ini inside terminal to see which files are used by PHP in CLI mode.

解决办法:

将composer.json里的”ext-http”: ““ 删除
将composer.lokc里的”ext-http”: “
“ 删除

第一次使用EasyWeChat微信支付SDK发现代码量很少,很简洁,但是在使用过程中也花了很多时间,遇到了很多问题

1、
第一次尝试时,发现下面的解释是当支付方式为APP时,才需要进行二次签名
//如trade_type = APP
//需要进行二次签名
所以第一次并没有进行二次签名,接口成功返回,但是一直报错支付验证签名失败

2、
尝试了几次后,进行二次签名验证再进行尝试,但是发现也是一直报错支付验证签名失败

3、之后就去微信支付接口签名校验工具,去验证签名
微信支付接口签名校验工具地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1
发现xml的验证结果是正确的

4、去百度查看别人分享的EasyWeChat使用方法,发现使用的二次加密的方法和官网的不一样,结果真的就解决了

$result = $app->jssdk->appConfig($prepayId);
官网文档写的:
(new \EasyWeChat\Payment\Jssdk\Client($app))->appConfig($result[‘prepay_id’]);

总结:官网只是简单的告诉SDK的用法,但是呢还是要结合看看自己的业务来进行调整和使用

thinkphp6 使用jwt报错
Call to undefined function sodium_base642bin()

解决:找到php.ini文件将extension=sodium前面的;号去除

保存后重启php

进入到mysql安装目录的bin目录下,运行cmd
输入mysql_upgrade -uroot -p,输入密码
然后重启mysql即可

1、index.html页面添加按钮,可以复制新增或者编辑下来改
#
btn-disabled disabled 添加这两个class属性就是勾选列表数据时,按钮才会高亮,才可以点击

<a href="javascript:;" class="btn btn-success btn_reviewer btn-disabled disabled" title="设置审核人" style="background: #66B1FF;"></i>设置审核人</a>

2、设置js
找到文件对应的js文件,添加url

reviewer_url: 'department/reviewer',

3、设置点击按钮弹窗js
找到require-table.js
添加按钮事件

直接复制添加的js下来改

4、可以给按钮自定义点击时间(看自己的需求是否需要)

这一步是必须要添加了,不然会加载不到框架的一些事件,比如下拉选择

场景:比如文章列表中的搜索,需要显示文章分类的下拉查询条件

visible:false 当前属性表示table列表中不显示当前的这个字段

找到文章的js文件
给文章分类的字段searchList添加查询数据


{field: 'article_category_id', title: '文章分类id', searchList:$.getJSON("article/article_category/searchlist")},

后端article_category控制器添加一个searchlist接口

    /**
     * 搜索下拉列表
     */
    public function searchlist()
    {
        $result = $this->model->select();
        $searchlist = [];
        foreach ($result as $key => $value) {
            $searchlist[] = ['id' => $value['id'], 'name' => $value['name']];
        }
        $data = ['searchlist' => $searchlist];
        $this->success('', null, $data);
    }

好的办公地址能减轻公司开支,和员工的心态

1、安静
不要选择马路边的场所,开窗会吵,关窗会闷

2、便宜
前期可以选择一些民房作为办公场所,1000左右

3、干净整齐,给人舒服的感觉

场景

需要获取数据表的菜单数据,并转换成树状结构返回给前端

方案

function list_to_tree($list, $parent_id = 0) {
    $tree = array();

    foreach ($list as $item) {
        if ($item['pid'] == $parent_id) {
            $children = list_to_tree($list, $item['id']);
            if (!empty($children)) {
                $item['children'] = $children;
            }
            $tree[] = $item;
        }
    }

    return $tree;
}

问题:PhpStorm 全局搜索失效

解决

  1. 判断快捷键是否被占用,导致“ctrl + shift + f”无法弹出全局搜索框
  2. 重置索引,可能是索引失效导致无法全局搜索
    File -> Invalidate Caches/Restart
    

原文链接:https://blog.csdn.net/qq_36025814/article/details/128513733

问题:PhpStorm 全局搜索失效

解决

  1. 判断快捷键是否被占用,导致“ctrl + shift + f”无法弹出全局搜索框
  2. 重置索引,可能是索引失效导致无法全局搜索
    File -> Invalidate Caches/Restart
    

获取相对当前时间一定距离的时间

一天后:stormtime("+1 day")
一小时后:stormtime("+1 hour")
一分钟后:stormtime("+1 minute")
一个月后:stormtime("+1 mouth")

相对某个时间一定距离的时间

一天后:stormtime("+1 day",时间戳)
一小时后:stormtime("+1 hour",时间戳)
一分钟后:stormtime("+1 minute",时间戳)
一个月后:stormtime("+1 mouth",时间戳)

要将 MySQL 数据库中某个表中的某个字段值从小写转换为大写,可以使用以下 SQL 更新语句:

UPDATE your_table_name SET your_field_name = UPPER(your_field_name);

请将 your_table_name 替换为你的表名,your_field_name 替换为你需要转换的字段名。执行该语句后,将会将该字段中所有的小写字符串转换为大写字符串。

注意,执行该 SQL 更新语句会永久修改数据库表中的数据,请谨慎操作,并在执行前先备份数据库。

为了保证前后端接口的兼容性,通常需要对接口进行版本管理。以下是一些示例常用的接口版本管理的方法:

  1. URI 版本控制:

    这种方法在 URI 上使用 URL path 来指定不同的版本,例如:

    • https://xyz.com/v1/xxx
    • https://xyz.com/v2/xxx

    这样我们可以通过 URL path 的版本号,快速区分不同版本的 API。

    示例代码如下:

    @RestController
    @RequestMapping("/api/v1")
    public class UserControllerV1 {
    
        @GetMapping("")
        public Result<UserDTO> getUsers() {
            // v1 版本用户端实现逻辑
        }
    }
    
    @RestController
    @RequestMapping("/api/v2")
    public class UserControllerV2 {
    
        @GetMapping("")
        public Result<UserDTOV2> getUsers() {
            // v2 版本用户端实现逻辑
        }
    
    }
    
  2. HTTP Header 版本控制:

    这种方法在 HTTP Header 中添加一个自定义的版本控制头,例如:

    • Api-Version: 1
    • Api-Version: 2

    客户端在请求时添加对应的版本号,服务端则通过解析请求头中的版本号来判断调用的是哪个版本的接口。

    示例代码如下:

    @RestController
    @RequestMapping("/api")
    public class UserController {
    
        @GetMapping("")
        public Result<UserDTO> getUsers(@RequestHeader("Api-Version") Integer version) {
            if (version == 1) {
                // v1 版本用户端实现逻辑
            } else if (version == 2) {
                // v2 版本用户端实现逻辑
            } else {
                // 其他版本的用户端实现逻辑
            }
        }
    
    }
    
  3. Query String 版本控制:

    这种方法在 Query String 中添加版本号参数,例如:

    • https://xyz.com/xxx?api-version=1
    • https://xyz.com/xxx?api-version=2

    这种方法和 HTTP Header 版本控制方法相似,只是将版本号放在 Query String 中。

    示例代码如下:

    @RestController
    @RequestMapping("/api")
    public class UserController {
    
        @GetMapping("")
        public Result<UserDTO> getUsers(@RequestParam("api-version") Integer version) {
            if (version == 1) {
                // v1 版本用户端实现逻辑
            } else if (version == 2) {
                // v2 版本用户端实现逻辑
            } else {
                // 其他版本的用户端实现逻辑
            }
        }
    
    }
    

无论采用哪种版本控制方式,重要的是在控制器中进行统一格式规范,利用文档工具(如 Swagger)进行明确定义和说明,以方便前端开发者调用不同版本的 API,同时也能方便后端开发者对接口进行维护和管理。

可以使用以下代码将Java中的整数列表(List<Integer>)转换为字符串数组:

List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);
String[] strArray = intList.stream()
                            .map(Object::toString)
                            .toArray(String[]::new);

这个代码使用Java 8的流操作将整数列表转换为字符串数组。具体来说,它使用流中的 map 方法将整数对象转换为字符串对象,然后使用 toArray 方法将其收集到一个字符串数组中。注意,这里的 map 方法使用 Object::toString 方法将整数对象转换为字符串。

场景

现在有两个分支,一个主分支,一个开发分支,开发分支上有多次提交,现在只想合并某次提交到主分支

解决方案

可以使用 git cherry-pick 命令将指定的提交合并到主分支。

具体步骤如下:

  1. 切换到主分支:
git checkout main
  1. 查看开发分支的提交历史:
git log --oneline <dev-branch>

其中,<dev-branch> 是开发分支的名字。

  1. 找到想要合并的提交的 ID,复制它。

  2. 将复制的提交 ID 应用到主分支中:

git cherry-pick <commit-id>

其中,<commit-id> 是刚刚复制的提交 ID。

  1. 如果有冲突,手动解决冲突,然后进行提交:
git add <冲突文件>      # 添加已解决冲突的文件
git cherry-pick --continue    # 继续进行 cherry-pick 操作
  1. 完成 cherry-pick 操作后,将改动推送到远程仓库:
git push

这样就可以将某次提交从开发分支合并到主分支了。

使用 groupBy()select() 方法。假设我们有一个 Order 实体类,其中包含一个状态属性 status 和一个价格属性 price,我们需要按照状态进行分组,统计每个状态的订单数量和总价格,可以使用以下代码:

QueryWrapper<Order> wrapper = new QueryWrapper<>();
wrapper.select("status", "count(*) as count", "sum(price) as total_price") // 选择需要统计的字段
       .groupBy("status"); // 按照状态分组

List<Map<String, Object>> orderStats = orderMapper.selectMaps(wrapper);

System.out.println(orderStats);

这里使用 selectMaps() 方法将查询结果转换为一个 Map 列表,其中每个 Map 包含状态、订单数量和总价格三个键值对。其中 count(*)sum(price) 是 SQL 中的聚合操作,这里可以在 select 语句中直接使用别名 as countas total_price 指定结果集中的字段名。

注意,查询结果中键值对的顺序与 select() 方法中指定字段的顺序一致。如果你需要更改顺序,可以使用 SQL 中的 as 关键字来指定别名。

除了使用 selectMaps() 方法,你还可以使用 selectObjs() 方法获取查询结果中的单个属性,或使用 selectList() 方法获取一个实体对象列表。

Java Spring 中,可以使用 Collectors.toMap() 方法将一个列表转换为 Map。假设我们有一个 Person 类型的对象列表,其中每个 Person 对象都有一个唯一的 ID 和一个姓名属性 name,我们可以使用以下代码将它们转换为 ID-Name 的键值对:

List<Person> personList = new ArrayList<>();
// TODO: add person objects to the list

Map<Integer, String> idNameMap = personList.stream()
        .collect(Collectors.toMap(Person::getId, Person::getName));

System.out.println(idNameMap);

这里使用 stream() 方法将列表转换为流,然后使用 Collectors.toMap() 将每个 Person 对象的 ID 和名称转换为一个键值对,并将这些键值对收集到一个 Map 中。其中 Person::getIdPerson::getName 是方法引用,分别代表获取 Person 对象中的 ID 和 name 属性。

以下是一个包含增删改查接口的基类的示例代码:

public abstract class BaseController<T extends BaseEntity, S extends BaseService<T>> {

    @Autowired
    protected S service;

    // 创建实体
    @PostMapping("")
    public Result create(@RequestBody T entity) {
        service.save(entity);
        return Result.success();
    }

    // 根据 ID 查询实体
    @GetMapping("/{id}")
    public Result getById(@PathVariable("id") Long id) {
        T entity = service.getById(id);
        return Result.success(entity);
    }

    // 更新实体
    @PutMapping("/{id}")
    public Result update(@PathVariable("id") Long id, @RequestBody T entity) {
        entity.setId(id);
        service.update(entity);
        return Result.success();
    }

    // 删除实体
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Long id) {
        service.removeById(id);
        return Result.success();
    }

    // 根据关键字和分页信息查询实体
    @GetMapping("")
    public Result query(String keyword, Integer pageNum, Integer pageSize) {
        IPage<T> page = service.query(keyword, pageNum, pageSize);
        return Result.success(page);
    }

    // 处理异常
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        log.error("Handle exception: ", e);
        return Result.failure(e.getMessage());
    }

}

在这个基类中,我们定义了一些通用的方法,例如:

  • create():用于创建指定类型的实体;
  • getById():用于获取指定 ID 的实体;
  • update():用于更新指定类型的实体;
  • delete():用于删除指定 ID 的实体;
  • query():用于根据关键字和分页信息查询实体;
  • handleException():用于统一处理异常。

这些方法被定义为公共方法,因此可以在具体的控制器中进行继承和重写,以进行必要的定制和扩展。同时,由于这些方法被封装在基类中,因此可以减少控制器中的重复代码,提高代码的复用性和可维护性。

├── src
│   ├── main
│   │   ├── java
│   │   │   ├── config
│   │   │   │   └── AppConfig.java
│   │   │   ├── controller
│   │   │   │   ├── UserController.java
│   │   │   │   └── HomeController.java
│   │   │   ├── dto
│   │   │   │   ├── UserDTO.java
│   │   │   │   └── ErrorResponseDTO.java
│   │   │   ├── entity
│   │   │   │   └── User.java
│   │   │   ├── exception
│   │   │   │   ├── BadRequestException.java
│   │   │   │   ├── CustomException.java
│   │   │   │   └── ResourceNotFoundException.java
│   │   │   ├── mapper
│   │   │   │   └── UserMapper.java
│   │   │   ├── repository
│   │   │   │   └── UserRepository.java
│   │   │   ├── service
│   │   │   │   ├── UserService.java
│   │   │   │   └── UserServiceImpl.java
│   │   │   ├── util
│   │   │   │   └── CommonUtils.java
│   │   │   └── vo
│   │   │       ├── UserVO.java
│   │   │       └── ResponseVO.java
│   │   ├── resources
│   │   │   ├── static
│   │   │   │   ├── images
│   │   │   │   └── scripts
│   │   │   ├── templates
│   │   │   │   ├── user.html
│   │   │   │   └── home.html
│   │   │   ├── application.properties
│   │   │   └── logback.xml
│   │   └── webapp
│   ├── test
│   ├── .gitignore
│   ├── LICENSE
│   ├── README.md
│   └── pom.xml

在这个例子中,config目录下只包含了一个AppConfig.java文件,该文件用于配置应用程序的一些配置项。

controller目录下包含了UserController.javaHomeController.java两个控制器文件,分别用于处理用户和主页的请求。

dto目录下包含了用于数据传输的UserDTO.javaErrorResponseDTO.java两个文件。

entity目录下包含了实体对象User.java

exception目录下包含了用于异常处理的CustomException.javaBadRequestException.javaResourceNotFoundException.java三个文件。

mapper目录下包含了UserMapper.java文件,用于对象转换。

repository目录下包含了UserRepository.java文件,用于数据的增删改查。

service目录下包含了UserService.javaUserServiceImpl.java两个文件,用于业务逻辑处理。

util目录下只添加了一个CommonUtils.java文件,用于放置一些通用的工具类。

vo目录下包含了UserVO.javaResponseVO.java两个文件,分别用于值对象和响应对象。

resources目录下,application.properties文件用于配置应用程序的一些属性,例如数据库连接等;logback.xml文件是logback日志的配置文件;static目录用于存放静态资源文件;templates目录下是用于存放模板文件。

README.md文件是项目说明文档,而.gitignore文件则是用于配置git版本控制中需要忽略的文件列表。LICENSE文件用于定义代码版权等相关信息。

你可以使用以下代码将Java中的整数列表(List<Integer>)转换为字符串数组:

List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);
String[] strArray = intList.stream()
                            .map(Object::toString)
                            .toArray(String[]::new);

这个代码使用Java 8的流操作将整数列表转换为字符串数组。具体来说,它使用流中的 map 方法将整数对象转换为字符串对象,然后使用 toArray 方法将其收集到一个字符串数组中。注意,这里的 map 方法使用 Object::toString 方法将整数对象转换为字符串。

1、性能提升:PHP7比PHP5.0性能提升了两倍。

2、以前的许多致命错误,现在改成抛出异常。

3、PHP 7.0比PHP5.0移除了一些老的不在支持的SAPI(服务器端应用编程端口)和扩展。

4、PHP 7.0比PHP5.0新增了空接合操作符。

5、PHP 7.0比PHP5.0新增加了结合比较运算符。

6、PHP 7.0比PHP5.0新增加了函数的返回类型声明。

7、PHP 7.0比PHP5.0新增加了标量类型声明。

8、PHP 7.0比PHP5.0新增加匿名类。

9、错误处理和64位支持

如果您了解错误和异常之间的区别,那么您就会知道在PHP 5中处理致命错误非常不容易。PHP7简化了流程,因为它已用可以轻松处理的异常替换了几个主要错误。这是通过引入新的引擎异常对象实现的。

您可能已经知道,PHP 5不支持64位整数或大文件,但PHP 7中的情况已发生变化。PHP7具有64位支持,因此您也可以使用本机64位整数作为大文件,因此,您可以在64位系统体系结构上完美运行应用程序。

10、声明返回类型

php数组键名转为小写的方法

array_change_key_case()函数来将数组键名(key)转为小写;
该函数可以将数组中所有的键(key)都转换为小写字母

使用场景

有时候我们需要修改数组的键名,比如获取excel表格的数据时候,获取到的表格数据的键名是:ABC

一维数组修改键名

$arr=array(1 => 1, 2 => "张三", 3 => 20);
$key=array("id","姓名","年龄");
$array=array_combine($key, $arr);

二维数组修改键名


$arr = [
    ["A" => 1, "B" => "张三", "C" => 20],
    ["A" => 2, "B" => "李四", "C" => 20]
];
$key = array("id","姓名","年龄");
foreach($arr as $key => $item){
    $arr[$key] = array_combine($key, $item);
}

使用场景

在二维数组处理过程中,需要对数据按某字段进行排序

方法

function sortByField($array,$field){
    $sort = array_column($array,$field);
    array_multisort($sort,SORT_ASC,$array);
    return $array;
}
$arr = [
    ['id'=>1,'name'=>'张三'],
    ['id'=>5,'name'=>'李四'],
];
$arr_sort = sortByField($arr,'id');

报错信息

安装lcobucci/jwt报错,报错信息如下

Problem 1
    - Root composer.json requires lcobucci/jwt ^4.1 -> satisfiable by lcobucci/jwt[4.1.0, ..., 4.2.1].
    - lcobucci/jwt[4.1.0, ..., 4.2.1] require ext-sodium * -> it is missing from your system. Install or enable PHP's sodium extension.

To enable extensions, verify that they are enabled in your .ini files:
    - /php/php-7.4.0/etc/php.ini

问题分析

lcobucci/jwt依赖ext-sodium拓展,但是系统不存在ext-sodium拓展,导致安装失败

问题处理

方法一:安装sodium拓展
打开/php/php-7.4.0/etc/php.ini配置文件,检查是否开启了sodium拓展

extension=sodium #去掉前面的分号

方法二:安装lcobucci/jwt的 3.4版本

背景

使用JWT解析字符串时报错

Object of class Lcobucci\JWT\Token\DataSet could not be converted to string

原因分析

单从字面上理解是对象不能转换为字符串,由于 object转换成 string 時才会发生这个严重错误(fatal error)。

可能原因

1、直接打印一个对象
2、把一个对象赋值给一个变量后,然后打印该变量

背景使用JWT解析字符串时报错

The JWT string must have two dots

原因分析

JWT字符串必定包含两个.号,出现改报错,说明解析的字符串不符合格式要求,可以是传错参数了

方法一:substr_count()函数是一个小字符串在一个大字符串中出现的次数:

$number = substr_count($big_string, $small_string);

substr_count("abcabc","a");

问题复现

使用ssh链接服务器

ssh root@ip地址

报以下错误


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx.
Please contact your system administrator.
Add correct host key in /Users/xxx/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/xxx/.ssh/known_hosts:46
ECDSA host key for ip地址 has changed and you have requested strict checking.
Host key verification failed.

问题原因

重置过服务器后,再次想访问会出现这个问题。

问题解决

ssh-keygen -R IP地址

1、编辑apache的httpd.conf文件

  • 设置允许覆盖
    AllowOverride All
    
  • 开启重写
    LoadModule rewrite_module modules/mod_rewrite.so
    

2、编辑.htaccess

  Options +FollowSymlinks
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

方法一:intval舍弃小数,保留整数
方法二:round四舍五入
方法三:ceil向上取整
方法四:floor向下取整
方法五:abs取绝对值

php常用函数:列表转树结构

function list_to_tree($list, $root = 0,$pk = 'id', $pid = 'pid', $child = '_child') {
    // 创建Tree
    $tree = array();
    if (is_array($list)){
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] = &$list[$key];
        } 
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId=0;
            if(isset($data[$pid])){
                $parentId =$data[$pid] ;
            }
            if ($root == $parentId) {
                $tree[] = &$list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent = &$refer[$parentId];
                    $parent[$child][] = &$list[$key];
                } 
            }
        } 
    }
    return $tree;
}

树转列表

function tree_to_list($tree, $level = 0,$pk = 'id', $pid = 'pid', $child = '_child'){
    $list = array();
    if (is_array($tree)){
        foreach($tree as $val) {
            $val['level']=$level;
            $child=$val['_child'];
            if(isset($child)){
                if (is_array($child)){
                    unset($val['_child']);
                    $list=$val;
                    $list = array_merge($list, tree_to_list($child,$level+1));
                }
            }else{
                $list=$val;
            }
        }
        return $list;
    }
}

php常用函数:列表转树结构

/**
 * 采用递归将数据列表转换成树
 *
 * @param $dataArr           数据列表
 * @param int $rootId        根节点ID
 * @param string $pkName     主键名
 * @param string $pIdName    父节点id名
 * @param string $childName  子节点名称
 * @return array
 */
function ListToTreeRecursive($dataArr, $rootId = 0, $pkName = 'id', $pIdName = 'parent_id', $childName = 'children')
{
    $arr = [];
    foreach ($dataArr as $sorData) {
        if ($sorData[$pIdName] == $rootId) {
            $children = ListToTreeRecursive($dataArr, $sorData[$pkName]);
            if($children){
                $sorData[$childName] = $children;
            }
            $arr[] = $sorData;
        }
    }

    return $arr;
}

1、left(str,length) 从左边截取length
2、right(str,length)从右边截取length
3、substring(str,index)当index > 0从左边开始截取直到结束 当index < 0从右边开始截取直到结束 当index = 0返回空
4、substring(str,index,len) 截取str,从index开始,截取len长度
5、substring_index(str,delim,count),str是要截取的字符串,delim是截取的字段count是从哪里开始截取(为0则是左边第0个开始,1位左边开始第一个选取左边的,-1从右边第一个开始选取右边的
6、subdate(date,day)截取时间,时间减去后面的day
7、subtime(expr1,expr2) 时分秒expr1-expr2

驼峰转下划

function HumpToUnderline($params) {
    $newArr = [];
    if (!is_array($params) || empty($params)) return $newArr;
    foreach ($params as $key => $val){
        $newkey = $key;
        if (!strstr($key, '_')) {
            $key = str_replace("_", "", $key);
            $key = preg_replace_callback('/([A-Z]{1})/', function ($matches) {
            return '_' . strtolower($matches[0]);
            }, $key);
            $newkey = ltrim($key, "_");
        }

        $newArr[$newkey] = is_array($val) ? humpUnderlineConversion($val, $type) : $val;
    }

    return $newArr;
}

下划线转驼峰

function UnderlineToHump($params) {
    $newArr = [];
    if (!is_array($params) || empty($params)) return $newArr;
    foreach ($params as $key => $val){
        $newkey = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) {
            return strtoupper($matches[2]);
        }, $key);
        $newArr[$newkey] = is_array($val) ? humpUnderlineConversion($val, $type) : $val;
    }

    return $newArr;
}

驼峰转下划

function HumpToUnderline($params) {
    $newArr = [];
    if (!is_array($params) || empty($params)) return $newArr;
    foreach ($params as $key => $val){
        $newkey = $key;
        if (!strstr($key, '_')) {
            $key = str_replace("_", "", $key);
            $key = preg_replace_callback('/([A-Z]{1})/', function ($matches) {
            return '_' . strtolower($matches[0]);
            }, $key);
            $newkey = ltrim($key, "_");
        }

        $newArr[$newkey] = is_array($val) ? humpUnderlineConversion($val, $type) : $val;
    }

    return $newArr;
}

下划线转驼峰

function UnderlineToHump($params) {
    $newArr = [];
    if (!is_array($params) || empty($params)) return $newArr;
    foreach ($params as $key => $val){
        $newkey = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) {
            return strtoupper($matches[2]);
        }, $key);
        $newArr[$newkey] = is_array($val) ? humpUnderlineConversion($val, $type) : $val;
    }

    return $newArr;
}
    //获取数据
    $categorys = $this->model->select();
    $categorys = collection($categorys)->toArray();


    //转成树结构展示
    //parent_id 父级id
    //nickname名称
    $tree = Tree::instance();
    $tree->init($categorys, 'parent_id');
    $this->catblist = $tree->getTreeList($tree->getTreeArray(0), 'nickname');
    $catbdata =[];
    foreach ($this->catblist as $k => $v)
    {
        $catbdata[$v['id']] = $v;
    }

    $this->view->assign("categorys", $catbdata);

效果展示:

匹配内容 正在表达式
匹配中文 [\u4e00-\u9fa5]
英文字母 [a-zA-Z]
数字 [0-9] 或者 [\D]
不能以_开头 (?!_)
不能以_结尾 (?!.*?_$)
数字、26个英文字母或者下划线组成的字符串 ^\w+$
匹配双字节字符 [^x00-xff]
空行 ^\s*\n$
Email地址 ^[a-zA-Z0-9][\w.-][a-zA-Z0-9]@[a-zA-Z0-9][\w.-][a-zA-Z0-9].[a-zA-Z][a-zA-Z.]*[a-zA-Z]$
手机号码 ^1\d{10}$

26、
在使用RegularExpressionValidator验证控件时的验证功能及其验证表达式介绍如下:
只能输入数字:“^[0-9]$”
只能输入n位的数字:“^d{n}$”
只能输入至少n位数字:“^d{n,}$”
只能输入m-n位的数字:“^d{m,n}$”
只能输入零和非零开头的数字:“^(0|[1-9][0-9]
)$”
只能输入有两位小数的正实数:“^[0-9]+(.[0-9]{2})?$”
只能输入有1-3位小数的正实数:“^[0-9]+(.[0-9]{1,3})?$”
只能输入非零的正整数:“^+?[1-9][0-9]$”
只能输入非零的负整数:“^-[1-9][0-9]
$”
只能输入长度为3的字符:“^.{3}$”
只能输入由26个英文字母组成的字符串:“^[A-Za-z]+$”
只能输入由26个大写英文字母组成的字符串:“^[A-Z]+$”
只能输入由26个小写英文字母组成的字符串:“^[a-z]+$”
只能输入由数字和26个英文字母组成的字符串:“^[A-Za-z0-9]+$”
只能输入由数字、26个英文字母或者下划线组成的字符串:“^w+$”
验证用户密码:“^[a-zA-Z]w{5,17}$”正确格式为:以字母开头,长度在6-18之间,
只能包含字符、数字和下划线。
验证是否含有^%&’,;=?$”等字符:“[^%&’,;=?$x22]+”
只能输入汉字:“^[u4e00-u9fa5],{0,}$”
验证Email地址:“^w+[-+.]w+)@w+([-.]w+).w+([-.]w+)$”
验证InternetURL:“^]
)?$”
验证身份证号(15位或18位数字):“^d{15}|d{}18$”
验证一年的12个月:“^(0?[1-9]|1[0-2])$”正确格式为:“01”-“09”和“1”“12”
验证一个月的31天:“^((0?[1-9])|((1|2)[0-9])|30|31)$”
正确格式为:“01”“09”和“1”“31”。
匹配中文字符的正则表达式: [u4e00-u9fa5]
匹配双字节字符(包括汉字在内):[^x00-xff]
匹配空行的正则表达式:n[s| ]r
匹配HTML标记的正则表达式:/<(.
)>.|<(.) />/
匹配首尾空格的正则表达式:(^s)|(s$)
匹配Email地址的正则表达式:w+([-+.]w+)@w+([-.]w+).w+([-.]w+)
匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]
)?

问题描述

导入xlsx后缀文件,报错Cannot open source table: Invalid variant operation

问题分析

之前导入都是正常的,可能是这个文件的格式影响到了navicat导入

问题解决

把xlsx另存为xls文件,导入成功

问题描述:使用PHPExcel 或者 Spreadsheet导出时,导出成功后打开文件后内容是乱码,或者是打开文件时提示错误窗口无法打开文件

问题1、php 导出excel打开后发现是乱码

问题2、php导出excel打开后提示无法打开文件问题

解决方法:

在导出方法头部添加 ob_end_clean(); 即可

方法一

git branch --set-upstream-to=origin/<远程分支> <本地分支>

方法二

git push -u origin <远程分支>

Shortcode是什么

WordPress Shortcode 指的是一些使用[]包含的短代码,WordPress会识别这些短代码并根据短代码的定义输出特定的内容。

Shortcode定义类型

Shortcode API 支持几乎所有可能的组合形式:自关闭标签,开放标签,含有参数的标签等。

[mycode]
[mycode foo="bar" ]
[mycode]Some Content(支持html)[/mycode] //包含内容
[mycode]Content [another-shotcode] more content[/mycode] //嵌套

Shortcode定义以及相关用法

function my_shortcode_func($attr, $content) {
    // $attr $key=>$value 的数组
    // $content 是 shortcode 中包含的字符串
    // 对 $attr 和 $content 进行处理
    // 返回预期的值
}
add_shortcode('mycode', 'my_shortcode_func')// 添加一个 Shortcode
remove_shortcode('mycode'); // 移除一个 Shortcode
remove_all_shortcodes(); // 移除所有的 Shortcode

使用场景

有时候需要禁止一些ip访问网站

相关函数

方法一:.htaccess设置

Deny from 192.168.9.9 #阻止一个IP
Deny from 192.168.0.0/24 #阻止一个IP段

方法二:Directory选项控制

<Directory "/var/www/web/">
Order allow,deny
Allow from all
Deny from 192.168.9.9 #阻止一个IP
Deny from 192.168.0.0/24 #阻止一个IP段
</Directory>

使用场景

有时候需要根据用户访问的设备类型进行相应的处理

相关函数

function is_mobile_request()  
{  
 $_SERVER['ALL_HTTP'] = isset($_SERVER['ALL_HTTP']) ? $_SERVER['ALL_HTTP'] : '';  
 $mobile_browser = '0';  
 if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|iphone|ipad|ipod|android|xoom)/i', strtolower($_SERVER['HTTP_USER_AGENT'])))  
  $mobile_browser++;  
 if((isset($_SERVER['HTTP_ACCEPT'])) and (strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml') !== false))  
  $mobile_browser++;  
 if(isset($_SERVER['HTTP_X_WAP_PROFILE']))  
  $mobile_browser++;  
 if(isset($_SERVER['HTTP_PROFILE']))  
  $mobile_browser++;  
 $mobile_ua = strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));  
 $mobile_agents = array(  
    'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',  
    'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',  
    'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',  
    'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',  
    'newt','noki','oper','palm','pana','pant','phil','play','port','prox',  
    'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',  
    'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',  
    'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',  
    'wapr','webc','winw','winw','xda','xda-'
    );  
 if(in_array($mobile_ua, $mobile_agents))  
  $mobile_browser++;  
 if(strpos(strtolower($_SERVER['ALL_HTTP']), 'operamini') !== false)  
  $mobile_browser++;  
 // Pre-final check to reset everything if the user is on Windows  
 if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'windows') !== false)  
  $mobile_browser=0;  
 // But WP7 is also Windows, with a slightly different characteristic  
 if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'windows phone') !== false)  
  $mobile_browser++;  
 if($mobile_browser>0)  
  return true;  
 else
  return false;
}

基础知识

在处理字符串过程中,为了保证数据正常的显示,以及网站的安全,需要对字符串进行处理

相关函数

  • htmlspecialchars
    将与、单双引号、大于和小于号化成HTML格式
  • htmlentities
    所有字符都转成HTML格式
  • addslashes
    单双引号、反斜线及NULL加上反斜线转义
  • stripslashes
    去掉反斜线字符
  • quotemeta
    加入引用符号
  • nl2br
    将换行字符转成<br>
  • strip_tags
    去掉HTML及PHP标记
  • mysql_real_escape_string
    转义SQL字符串中的特殊字符

基础知识

每个数组中都有一个内部的指针指向它的”当前”元素,初始指向插入到数组中的第一个元素。

相关函数

  • end($array) - 将内部指针指向数组中的最后一个元素,并输出
  • next($array) - 将内部指针指向数组中的下一个元素,并输出
  • prev($array) - 将内部指针指向数组中的上一个元素,并输出
  • reset$array() - 将内部指针指向数组中的第一个元素,并输出
  • each$array() - 返回当前元素的键名和键值,并将内部指针向前移动
  • current($array) 函数返回数组中的当前元素的值。
  • key($array) 获取当前元素的key

基础知识

每个数组中都有一个内部的指针指向它的”当前”元素,初始指向插入到数组中的第一个元素。

相关函数

  • end($array) - 将内部指针指向数组中的最后一个元素,并输出
  • next($array) - 将内部指针指向数组中的下一个元素,并输出
  • prev($array) - 将内部指针指向数组中的上一个元素,并输出
  • reset$array() - 将内部指针指向数组中的第一个元素,并输出
  • each$array() - 返回当前元素的键名和键值,并将内部指针向前移动
  • current($array) 函数返回数组中的当前元素的值。
  • key($array) 获取当前元素的key

问题场景:

在我们平时程序当中,如果字符串中出现了控制字符,json_decode 和 simplexml_load_string 这些函数就会失败

什么是控制字符

控制字符(Control Character),或者说非打印字符,出现于特定的信息文本中,表示某一控制功能的字符,如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通讯专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等。

具体控制字符一共有下面两个集合:

  • 七位ASCII定义了33个代码作为控制字符,它们是0到31、以及127,(位于0x00-0x1F及0x7F)。
  • 兼容的八位ISO/IEC 8859-1加上了从ISO/IEC 6429定义的从128到159的32个代码,位于0x80-0x9F。

php 移除控制字符

preg_replace('/[\x00-\x1F\x7F-\x9F]/u', '', $str);

需求场景:

今有一个列表,列表中某字段A,是逗号间隔的列表字符串。需要从列表中,查询条件为A字段查询包含某数值z的结果。

使用

select * from table where find_in_set(z,A)

与in的区别

select * from table where A in (z)
只能完全匹配

与like 的区别

模糊匹配,坑存在的问题,查询1可能查询到11
select * from table where A like '%z%'

安装 - phpexcel

composer require phpoffice/phpexcel

1.设置excel属性

1.创建人

$objPHPExcel->getProperties()->setCreator("HuangJu");

2.最后修改人

$objPHPExcel->getProperties()->setLastModifiedBy("JJ");

3.标题

$objPHPExcel->getProperties()->setTitle("office2007 document");

4.题目

$objPHPExcel->getProperties()->setSubject("office2007 document");

4.题目

$objPHPExcel->getProperties()->setDescription("office2007 document");

5.关键字

$objPHPExcel->getProperties()->setKeywords("office2007 document");

5.种类

$objPHPExcel->getProperties()->setCategory("office2007 document");

5.设置当前sheet

$objPHPExcel->setActiveSheetIndex(0);

5.设置sheet的name

$objPHPExcel->getActiveSheet()->setTitle('name1');

6.设置单元格的值

$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Str');
$objPHPExcel->getActiveSheet()->setCellValue('A2', 12);
$objPHPExcel->getActiveSheet()->setCellValue('A3', true);
$objPHPExcel->getActiveSheet()->setCellValue('B1', '=SUM(C2:C4)');
$objPHPExcel->getActiveSheet()->setCellValue('B2', '=MIN(B1:B2)');

7.合并单元格

$objPHPExcel->getActiveSheet()->mergeCells("A1:E22");

8.分离单元格

$objPHPExcel->getActiveSheet()->unmergeCells('A28:E29');

9.保护cell

// Needs to be set to true in order to enable any worksheet protection!
$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true);
$objPHPExcel->getActiveSheet()->protectCells('A3:E13', 'PHPExcel');

10.设置格式

// Set cell number formats
echo date('H:i:s') . " Set cell number formats";
$objPHPExcel->getActiveSheet()->getStyle('E4')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);
$objPHPExcel->getActiveSheet()->duplicateStyle($objPHPExcel->getActiveSheet()->getStyle('E4'), 'E5:E13');

11.设置宽width

//Set column width
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12);

12.设置font

$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setName('Candara');
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setSize(20);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);

13.设置align

$objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY);
//垂直居中
$objPHPExcel->getActiveSheet()->getStyle('B1')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);

14.设置column的border

$objPHPExcel->getActiveSheet()->getStyle('A4')->getBorders()->getTop()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);

14.设置border的color

$objPHPExcel->getActiveSheet()->getStyle('A4')->getBorders()->getLeft()->getColor()->setRGB('FF993300');
$objPHPExcel->getActiveSheet()->getStyle('A4')->getBorders()->getLeft()->getColor()->setARGB('FF993300');

15.设置填充颜色

$objPHPExcel->getActiveSheet()->getStyle('A4')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$objPHPExcel->getActiveSheet()->getStyle('A4')->getFill()->getStartColor()->setARGB('FF808080');

16.加图片

$objDrawing = new PHPExcel_Worksheet_Drawing();
$objDrawing->setName('Logo');
$objDrawing->setDescription('Logo');
$objDrawing->setPath('./test.jpg');
$objDrawing->setHeight(36);
$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());

$objDrawing = new PHPExcel_Worksheet_Drawing();
$objDrawing->setName('Paid');
$objDrawing->setDescription('Paid');
$objDrawing->setPath('./test.png');
$objDrawing->setCoordinates('B15');
$objDrawing->setOffsetX(110);
$objDrawing->setRotation(25);
$objDrawing->getShadow()->setVisible(true);
$objDrawing->getShadow()->setDirection(45);
$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());

17.处理中文输出问题
需要将字符串转化UTF-8编码,才能正常输出,否则中文字符输出空白,如下处理:
$str = iconv(‘gb2312’, ‘utf-8’, $str);
或者可以写一个函数专门处理中文字符

function convertUTF($str){
    if(empty($str)) return '';
    return iconv('gb2312', 'utf-8', $str); 
}

从数据库输出数据处理方式 — 读取如下

$dbconfig = array();
$db = new Mysql($dbconfig);
$sql = "SELECT * FROM tabel_name";
$row = $db->GetAll($sql);  // $row 为二维数组

$count = count($row);
for ($i = 2; $i <= $count + 1; $i++){
    $objPHPExcel->getActiveSheet()->setCellValue('A', $i, convert_uuencode($row[$i-2][1])); // 
    $objPHPExcel->getActiveSheet()->setCellValue('B', $i, convert_uuencode(date('Y-m-d', $row[$i-2][2])));
}

使用PHPEXcel判别和格式化Excel中的日期格式的例子
phpexcel导出的颜色与网页中颜色不一致的解决方法
CI中使用PHPExcel导出数据到Excel

echo date('H:i:s') . 'Create new Worksheet object\n';
$objPHPExcel->createSheet();

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
$objWriter-save('php://output');

实例

include 'PHPExcel.php';
include 'PHPExcel/Wrter/Excel2007.php';
// 或者include 'PHPExcel/Writer/Excel5.php'; 用于输出 .xls 的
// 创建一个excel
$objPHPExcel = new PHPExcel();

// 保存excel-2007格式
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
// 或者$objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); 非2007格式
$objWriter->save('xxx.xlsx');

// 直接输出到浏览器
$objWriter = new PHPExcel_Writer_Excel5($objPHPExcel);
header('Pragma:public');
header('Expires: 0');
header('Cache-Control:must-revalidate.post-check=0,pre-check=0');
header('Content-Type:application/force-download');
header('Content-Type:application/vnd.ms-execl');
header('Content-Type:application/octet-stream');
header('Content-Type:application/download');
header('Content-Disposition:attachment;filename="resume.xls"');
header("Content-Transfer-Encoding:binary");
$objWriter->save('php://output');

2.读取

1.读取文件

$objPHPExcel = PHPExcel_IOFactory::load($inputFileName);

2.特定类读取

$objReader = new PHPExcel_Reader_Excel5();
$objPHPExcel = $objReader->load($inputFileName);

3.创建读取类

$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);

读取类型有 Excel5、Excel2007、Excel2003XML、OOCalc、SYLK、Gnumeric、CSV
4.鉴别读取类

$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileType);

5.只读数据,忽略格式(对Excel读取,有很大优化)

$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setReadDataOnly(true);
$objReader->load($inputFileName);

6.加载Excel所有工作表

$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setLoadAllSheets(); //加载所有的工作表
$objPHPExcel = $objReader->load($inputFileName);
$objPHPExcel->getSheetCount();  // 获取工作表个数
$objPHPExcel->getSheetNames(); // 获取所有工作表名字组

7.加载单个命名工作表

$sheetname = 'Data Sheet #2';  // 单个工作表,传入字符串
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setLoadSheetsOnly($sheetname);
$objPHPExcel = $objReader->load($inputFileName);

8.加载多个命名的工作表

$sheetnames = array('Data Sheet 1', 'Data Sheet 2');
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objReader->setLoadSheetOnly($sheetnames);
$objPHPExcel = $objReader->load($inputFileName);

9.自定义一读取过滤器

class MyReadFilter implements PHPExcel_Reader_IReadFilter{          
    public function readCell($column, $row, $worksheetName = '') {
        // 只读去1-7⾏&A-E列中的单元格              
        if ($row >= 1 && $row <= 7) {                  
            if (in_array($column,range('A','E'))) {                      
                return true;                  
            }              
        }              
        return false;          
    }      
}      

$filterSubset = new MyReadFilter();      
$objReader = PHPExcel_IOFactory::createReader($inputFileType);      
$objReader->setReadFilter($filterSubset);        
// 设置实例化的过滤器对象      
$objPHPExcel = $objReader->load($inputFileName);

10.同样是自定义一个读取过滤器,但可配置读取的行和列范围

class MyReadFilter implements PHPExcel_Reader_IReadFilter{          
    private $_startRow = 0;     
    // 开始⾏          
    private $_endRow = 0;       
    // 结束⾏          
    private $_columns = array();    
    // 列跨度          
    public function __construct($startRow, $endRow, $columns) {              
        $this->_startRow = $startRow;              
        $this->_endRow       = $endRow;              
        $this->_columns      = $columns;          
    }          
    public function readCell($column, $row, $worksheetName = '') {              
        if ($row >= $this->_startRow && $row <= $this->_endRow) {                  
            if (in_array($column,$this->_columns)) {                      
                return true;                  
            }              
        }              
        return false;          
    }
}

判断{函数/类/方法/属性}是否存在

//(1)判断类是否存在
bool class_exists(string $class_name [, bool $autoload = true])
//(2)判断系统函数或自己写的函数是否存在
bool function_exists(string $function_name) 
//(3)判断类里面的某个方法是否已经定义
bool method_exists(mixed $object, string $method_name) 
//(4)判断类里面的某个属性是否已经定义
bool property_exists(mixed $class, string $property)

数组操作相关函数

一.排序类:【1.无返回值,传值引用,就直接对原数组进行了修改】
sort() 函数用于对数组单元从低到高进行排序。
rsort() 函数用于对数组单元从高到低进行排序。
ksort() 函数用于对键名从低到高进行排序并保持索引关系。
krsort() 函数用于对键名从高到低进行排序并保持索引关系。
asort() 函数用于对数组单元从低到高进行排序并保持索引关系。
arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。
natsort() 函数用于对数组单元从低到高进行区分大小写的排序并保持索引关系。
natcasesort() 函数用于对数组单元从低到高进行不区分大小写的排序并保持索引关系。大写在前,小写在后。
usort($arr,”strnatcmp”) 回调类的排序,把$arr数组里的每一个元素丢到strnatcmp()[非自然数排序]处理【返回新的排序数组】
二.键值操作类:【都有返回值,没有在原来参数上修改】
1.array_values($arr);//获取$arr中的值重排,去掉下标【返回值新索引数组】
2.array_keys($arr[,”str”,true])//获取$arr中所有字符是”str”的下标,形成索引数组,true表示区分大小写【返回新索引数组】
3.array_search(“is”,$arr[,true]) //返回值”is”在$arr中的key,找不到返回fales,true表示严格按照类型(8,”8”)【返回第一个匹配值】
4.in_array(“str”,$arr);//判断”str”在$arr中是否存在,【返回BOOL】
5.is_array($arr);//判断是否是数组【返回BOOL】
6.array_key_exists($key,$arr); //查询$arr中是否有$key,【返回BOOL】
7.array_flip($arr);// 交换键值,如有重复,后来居上,【返回新数组】
8.array_reverse($arr,[true|false]);//数组顺序反转,param2是否保留原来键值【返回新关联/索引数组】
9.array_column(array(),’name’[,name_two]) — 返回数组中指定的name列[可选参数,如果有返回name=>name_two的形式]【返回一维数组】

三.元素个数和唯一性
1.array_unique($arr);//去掉$arr中的重复值,重复的保留第一个值,【返回数组,键值保留】
2.array_count_values($arr)//统计数组值出现的次数,【返回数组,KEY为原来数组的值,VALUE为统计的次数】
3.count($arr[,1])/sizeof();//统计$arr的元素个数,参数”1”表示统计多维数组开启,默认0为关闭【返回统计个数】

四.回调函数
1.array_filter($arr,”function”);//把$arr放到函数function中处理,【返回判断为TRUE的数据组成新数组,键值保留】
2.array_walk($arr,”function”[,”data”]);//把$arr放到function(&$v,$k,$data)中处理【返回值为bool】
3.array_map(“function”,$arr,$arr2,$arr3,….);//把所有数组返回到回调函数统一处理,【返回数组】
4.array_reduce($arr,myfunction[,initial]):把一维数组$arr中的值依次传到自定义函数myfunction($v1,$v2)的v2上,v1为累加值类似 于( .= ),[如果有initial,先把其当v1传进去]【返回字符串】

字符串处理函数

substr(字符串,开始地方,[返回字符串的长度]);// 截取字符串的一部分,第一个字符位置为0
substr_replace($str,"aaa",start[,length]);在$str上操作,从第start个开始,把【后边】的字符[全/或length个]替换
sub_count($str,"is"[,5,10]);//[ 从第五个字符开始,搜索长度为10,]搜索is在$str中出现的次数,【返回次数】
strstr($email,"@"[,true])    //从头开始搜索,无true返回@后边字符,有true返回@前边的字符[strrchr对比]
strrchr($email,"@")//从结尾开始搜索,返回@后的所有字符
str_replace(被替换词,替换词,被搜索字符串,[统计替换次数$num])   前两个参数也可为数组,两个数组元素个数相同
str_repeat($str,num);//重复$str字符串 num次,
strpos($str,"@");//返回@【第一次出现的位置】
strrpos($str,"@");//返回@【最后一次出现的位置】
str_word_count($str[,0/1/2]);
//返回$str中单词的数量[0指返回次数,默认值/1指以数组形式返回单词值/2指返回关联数组,k为单词首字母下标,v单词值]
strcmp($str1,$str2);//按ASCII码比较 str1>str2 则返回1 相等返回0 <返回-1  strcasecmp不区分大小写的比较
strnatcmp($str1,$str2);//按自然数的排序比较,上边的比较10<2;本函数比较10>2,按自然数大小来的
strcasecmp($str1,$str2);strnatcasecmp//以上4个函数,$str1,$str2比较,【返回值:相等0,小于-1,大于1】
strlen($string);成功则返回字符串 $string 的长度
mb_strlen($string,'utf8');//获取字符串$string长度,多字节的字符被计为 1。
explode(",",$str[,$limit_num]);//把$str按照","分割成一个数组[可选参数为返回数组的元素个数]【返回一个分割后的数组】
impolde("+",$arr);//把$arr里的元素按照“+”链接成一个字符串

文本处理函数

strtoupper($str)//字母全转为大写【返回全大写字符串】
strtolower()//字母全转为小写【返回全小写字符串】
str_pad($str,length,[---,STR_PAD_BOTH]); //在$str的两边填补“---“,注意,length若小于$str长度,不填补    
trim($str[,"a",STR_PAD_BOTH])// 去除两边/左/右的空白或"a",默认是空白,或自定义字符
ucfirst()//整个$str首字母大写
ucword()//$str每个单词首字母大写
iconv( from_charset ; to_charset,$str);        //转化字符格式     $file_name = iconv("gb2312","utf-8",$file_name);

HTML类处理相关函数

htmlspecialchars($str)//函数把【预定义字符】转换为【 HTML 实体】,&转换成&
htmlspecialchars_decode($str);//把【HTML实体】转换成【预定义字符】,&转换成&
htmlentities($str); //函数把【预定义字符】转换为【 HTML 实体】,&转换成&,有乱码问题,注意第二第三个参数,若编码不正确,会在实体化时把信息丢失
html_entity_decode($str) //把【HTML实体】转换成【预定义字符】,&转换成&,  > 转成 <
addslashes($html);      //添加转义字符“/”
stripslashes($html);       //删除转义字符“/”
strip_tags($html);   //去除HTML标签
nl2br($str)   //在$str中的换行/n前插入<br>,因为\n在源码可以换行,但是在浏览器窗口不行,有这个就可以

正则函数

preg_match($pattern,$subject,$arr);//按正则$pattern处理$subject,第一次匹配结果返回到数组中【函数的返回值为匹配次数】
preg_match_all($pattern,$subject,$arr)//按正则$pattern处理$subject,全部匹配结果返回到数组中【函数的返回值为匹配次数】
preg_replace()//正则替换字符串
preg_split($pattern,$str);//通过一个正则表达式分隔字符串【返回值为数组】

时间相关函数

date_default_timezone_set()('PRC');//设置时区为中国
time();//默认获取当前时间,【返回时间戳格式】
micritime();//获取当前时间【返回毫秒的时间戳】
mktime(H,i,s,m,d,Y)//指定时间转为时间戳,参数为空的时候作用与time()相同【返回时间戳格式】
strtotime('2015-10-10 10:10:10');//指定时间转换为时间戳【返回时间戳】
date("Y-m-d H:i:s",time());//转换时间戳为日期格式【返回目标格式的字符串】
date_diff()//两个时间之差

文件处理函数

file_exists($file)//文件是否存在,【true/false】
filesize($file)  //返回文件的大小【大小字节/出错false】
is_readable($file)//是否可读【返回bool】
is_writeable($file)//是否可写【返回bool】
is_executable($file)//是否可执行【返回bool】
filectime($file)//文件创建时间【时间戳】
filemtime($file)//文件修改时间【时间戳】
fileatime($file)//文件访问时间【时间戳】
stat($file)//返回文件的大部分信息【文件信息数组】
fopen($fileName,"模式字符r,w,x")//打开一个文件,【返回值为资源型$handle】
fclose($handle)    //关闭打开的文件【返回BOOL】
fwrite($handle,"$data")//把$data写入$handle文件,先清空后写入,【成功返回$handle,失败返回false】
file_put_contents($filename,$data);//它是上边三个合起来的效果
file_get_contents($filename)//读取文件里的信息【返回字符串】
flock($handle,$operation)    //用$operation锁定文件$handle,$operation取值有4种:
    LOCK_SH(PHP 4.0.1 以前的版本设置为 1):取得共享锁定(读取的程序)
    LOCK_EX(PHP 4.0.1 以前的版本中设置为 2):取得独占锁定(写入的程序)
    LOCK_UN(PHP 4.0.1 以前的版本中设置为 3):释放锁定(无论共享或独占)
    LOCK_NB(PHP 4.0.1 以前的版本中设置为 4):不让 flock() 在锁定时堵塞
copy($file1,$file2);//文件的复制。赋值$file1,形成$file2【返回BOOL】
unlink($file);//删除$file文件【返回BOOL】
rename($file1,$file_new_name);//重命名【返回BOOL】

目录处理函数

basename($file) //返回文件名,index.php
dirname($file)  //返回文件的路径,c://php/
pathinfo($file) //返回该文件路径的所有信息  ["dirname"目录名] ["basename"文件名] ["extension"文件后缀]
filesize($file)  统计大小
mkdir("dir_name");//建立一个空的目录
copy($org,$to) //复制
rmdir("dir_name");//删除一个空的目录
unlink("file_name")//删除一个文件,当删除目录是,必须删除该目录下的文件
opendir($file) //打开一个目录,参数为目录名或目录路径【返回资源型的目录句柄$dir_handle,无权限返false】
readdir($dir_handle) //读取目录,参数为目录句柄,while,返回当前指向对象的名字,目录指针后移【返回filename,没有是返false】
is_dir($dir) //判断是否是目录
closedir($dir_handle)  //关闭打开的目录
rewinddir($dir_handle) //倒回目录句柄,将目录指针重置到目录开始

数学相关函数

ceil()//向上取整
floor()//向下取整
round();//四舍五入
abs();//取绝对值
rand(10,100)//随机取值
mt_rand(10,100)//随机取值,算法不同,速度更快
fmod()//返回除法浮点形余数
max(int/$arr)//取最大值
min(int/$arr)//取最小值
pow(1024,2)//返回1021的2次幂

URL编码

urlencode($url)//对该URL进行编码;原因:防止乱码,解决空格等字符不能传递问题,form也是此编码格式传递
urldecode($url)//对该URL进行解码
parse_url($url)//返回该URL的所有信息,[scheme协议][host域名] [path路径][query参数]  【返回含信息的数组】
pathinfo($url)//["dirname"目录名] ["basename"文件名] ["extension"文件后缀]【返回含信息的数组,下标不同】
get_meta_tags($url)//获取该页面的所有META标签【返回关联数组】

JSON相关函数

json_encode($data);//对变量进行JSON编码
json_decode($data,true)//对JSON格式的字符串进行解码
json_last_error();//返回最后一次反生的错误

序列化

serialize()//返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。
unserialize()//对单一的已序列化的变量进行操作,将其转换回 PHP 的值。

相关函数

serialize() //函数用于序列化对象或数组,并返回一个字符串。
unserialize()//对JSON格式的字符串进行解码

基础用法

  1. serialize
     $sites = array('Google', 'Runoob', 'Facebook');
     $serialized_data = serialize($sites);
     echo  $serialized_data . PHP_EOL;
    

相关函数

serialize() //函数用于序列化对象或数组,并返回一个字符串。
unserialize()//对JSON格式的字符串进行解码

基础用法

  1. serialize
     $sites = array('Google', 'Runoob', 'Facebook');
     $serialized_data = serialize($sites);
     echo  $serialized_data . PHP_EOL;
    

相关函数

json_encode($data);//对变量进行JSON编码
json_decode($data,true)//对JSON格式的字符串进行解码
json_last_error();//返回最后一次反生的错误

基础用法

  1. json_decode
     //mixed json_decode ( string $json [, bool $assoc ] )
     //json待解码的 json string 格式的字符串。
     //assoc当该参数为 TRUE 时,将返回array而非 object 。默认false
     $json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
     var_dump(json_decode($json));
     var_dump(json_decode($json, true));
    

相关函数

preg_match();
preg_match_all();
preg_replace();
preg_split();
preg_filter
preg_quote
preg_replace_callback_array
preg_replace_callback
preg_grep

基础用法

  1. preg_match
     $subject = "abcdef";
     $pattern = '/^def/';
     $result = preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
     //$result 返回0或者1
     //$matches 匹配结果
    
  2. preg_match_all
     $subject = "abcdefabcabcabc";
     $pattern = '/^abc/';
     $result = preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
     //$result 返回匹配到的结果数量
     //$matches 匹配结果,对结果排序使 $matches[0] 为全部模式匹配的数组,$matches[1] 为第一个括号中的子模式所匹配的字符串组成的数组,以此类推。(即$matches[0] [0]为全部模式匹配中的每一项,$matches[0] [1]为全部模式匹配中的第二项,$matches[1] [0]为匹配每一个括号中的第一项,$matches[1] [1]为匹配每一个括号中的第二项)
    
  3. preg_replace

     //preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
     //$pattern: 要搜索的模式,可以是字符串或一个字符串数组。
     //$replacement: 用于替换的字符串或字符串数组。
     //$subject: 要搜索替换的目标字符串或字符串数组。
     //$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
     //$count: 可选,为替换执行的次数。
     $string = 'google 123, 456';
     $pattern = '/(\w+) (\d+), (\d+)/i';
     $replacement = 'runoob ${2},$3';
     echo preg_replace($pattern, $replacement, $string);
    
     $string = 'The quick brown fox jumped over the lazy dog.';
     $patterns = array();
     $patterns[0] = '/quick/';
     $patterns[1] = '/brown/';
     $patterns[2] = '/fox/';
     $replacements = array();
     $replacements[2] = 'bear';
     $replacements[1] = 'black';
     $replacements[0] = 'slow';
     echo preg_replace($patterns, $replacements, $string);
    
  4. preg_split
     //array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )
     //$pattern: 用于搜索的模式,字符串形式。
     //$subject: 输入字符串。
     //$limit: 可选,如果指定,将限制分隔得到的子串最多只有limit个,返回的最后一个 子串将包含所有剩余部分。limit值为-1, 0或null时都代表"不限制", 作为php的标准,你可以使用null跳过对flags的设置。
     //$flags: 可选,可以是任何下面标记的组合(以位或运算 | 组合):
     //PREG_SPLIT_NO_EMPTY: 如果这个标记被设置, preg_split() 将进返回分隔后的非空部分。
     //PREG_SPLIT_DELIM_CAPTURE: 如果这个标记设置了,用于分隔的模式中的括号表达式将被捕获并返回。
     //PREG_SPLIT_OFFSET_CAPTURE: 如果这个标记被设置, 对于每一个出现的匹配返回时将会附加字符串偏移量. 注意:这将会改变返回数组中的每一个元素, 使其每个元素成为一个由第0 个元素为分隔后的子串,第1个元素为该子串在subject 中的偏移量组成的数组。
     //使用逗号或空格(包含" ", \r, \t, \n, \f)分隔短语
    $keywords = preg_split("/[\s,]+/", "hypertext language, programming");
    print_r($keywords);
    

相关函数

date_default_timezone_set()('PRC');//设置时区为中国
time();//默认获取当前时间,【返回时间戳格式】
micritime();//获取当前时间【返回毫秒的时间戳】
mktime(H,i,s,m,d,Y)//指定时间转为时间戳,参数为空的时候作用与time()相同【返回时间戳格式】
strtotime('2015-10-10 10:10:10');//指定时间转换为时间戳【返回时间戳】
date("Y-m-d H:i:s",time());//转换时间戳为日期格式【返回目标格式的字符串】
getdate()//获取当前时间,【返回一个数组,参数年,月,日等都有】
date_diff() //
date_add() 
date_sub()
idate()

常用功能

  1. 格式化时间戳
     $time = time();
     echo date_format($time,"Y/m/d H:i:s");
     echo date("Y/m/d H:i:s",$time);
    
  2. 时间戳转日期
     $time = strtotime("2022-01-18 08:08:08");  // 将指定日期转成时间戳 
     // 打印当前时间  PHP_EOL 换行符,兼容不同系统
     echo  $time, PHP_EOL;
     // 更多实例
     echo strtotime("now"), PHP_EOL;
     echo strtotime("10 September 2000"), PHP_EOL; //
    
  3. 获取几天前/后的日期
     echo strtotime("+1 day"), PHP_EOL;
     echo strtotime("+1 week"), PHP_EOL;
     echo strtotime("+1 week 2 days 4 hours 2 seconds"), PHP_EOL;
     echo strtotime("next Thursday"), PHP_EOL;
     echo strtotime("last Monday"), PHP_EOL;
    
  4. 计算两个时间的差
     $date1=date_create("2013-03-15");
     $date2=date_create("2013-12-12");
     $diff=date_diff($date1,$date2);
    

相关函数

date_default_timezone_set()('PRC');//设置时区为中国
time();//默认获取当前时间,【返回时间戳格式】
micritime();//获取当前时间【返回毫秒的时间戳】
mktime(H,i,s,m,d,Y)//指定时间转为时间戳,参数为空的时候作用与time()相同【返回时间戳格式】
strtotime('2015-10-10 10:10:10');//指定时间转换为时间戳【返回时间戳】
date("Y-m-d H:i:s",time());//转换时间戳为日期格式【返回目标格式的字符串】
getdate()//获取当前时间,【返回一个数组,参数年,月,日等都有】
date_diff() //
date_add() 
date_sub()
idate()

常用功能

  1. 格式化时间戳
     $time = time();
     echo date_format($time,"Y/m/d H:i:s");
    
  2. 时间戳转日期
     $time = strtotime("2022-01-18 08:08:08");  // 将指定日期转成时间戳 
     // 打印当前时间  PHP_EOL 换行符,兼容不同系统
     echo  $time, PHP_EOL;
     // 更多实例
     echo strtotime("now"), PHP_EOL;
     echo strtotime("10 September 2000"), PHP_EOL; //
    
  3. 获取几天前/后的日期
     echo strtotime("+1 day"), PHP_EOL;
     echo strtotime("+1 week"), PHP_EOL;
     echo strtotime("+1 week 2 days 4 hours 2 seconds"), PHP_EOL;
     echo strtotime("next Thursday"), PHP_EOL;
     echo strtotime("last Monday"), PHP_EOL;
    
  4. 计算两个时间的差
     $date1=date_create("2013-03-15");
     $date2=date_create("2013-12-12");
     $diff=date_diff($date1,$date2);
    

相关函数

getimagesize获取图片大小信息
imagecreatetruecolor:创建新的true-color图像。此函数返回给定尺寸的空白图像。
imagecreatefromgif:返回一图像标识符,代表了从给定的文件名取得的图像。
imagecreatefromjpeg:返回一图像标识符,代表了从给定的文件名取得的图像。
imagecopyresampled:放大缩小裁剪图片
imagegif:以 GIF 格式将图像输出到浏览器或文件
imagejpeg:以 JPEG 格式将图像输出到浏览器或文件
imagepng:以 PNG 格式将图像输出到浏览器或文件
imagewbmp:以 WBMP 格式将图像输出到浏览器或文件
imagedestroy: 指令销毁图像资源以释放内存,虽然该函数不是必须的,但使用它是一个好习惯。

 /**
 * desription 压缩图片
 * @param sting $imgsrc 图片路径
 * @param string $imgdst 压缩后保存路径
 */
 private function compressedImage($imgsrc, $imgdst) {
     list($width, $height, $type) = getimagesize($imgsrc);
     $new_width = $width>800?800:$width;//图片宽度的限制
    $new_height =$height>800?ceil($height*800/$width):$height;//自适应匹配图片高度
     switch ($type) {
         case 1:
         $giftype = $this->check_gifcartoon($imgsrc);
         if ($giftype) {
         $image_wp = imagecreatetruecolor($new_width, $new_height);
         $image = imagecreatefromgif($imgsrc);
         imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // 复制图片
         //90代表的是质量、压缩图片容量大小
         imagejpeg($image_wp, $imgdst, 90); // 保存图片
         imagedestroy($image_wp); //释放图片
         imagedestroy($image);//释放图片
         }
         break;
         case 2:
         $image_wp = imagecreatetruecolor($new_width, $new_height);
         $image = imagecreatefromjpeg($imgsrc);
         imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // 复制图片
         //90代表的是质量、压缩图片容量大小
         imagejpeg($image_wp, $imgdst, 90);// 保存图片
         imagedestroy($image_wp);//释放图片
         imagedestroy($image);//释放图片
         break;
         case 3:
         $image_wp = imagecreatetruecolor($new_width, $new_height);
         $image = imagecreatefrompng($imgsrc);
         imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); // 复制图片
         //90代表的是质量、压缩图片容量大小
         imagejpeg($image_wp, $imgdst, 90);// 保存图片
         imagedestroy($image_wp);//释放图片
         imagedestroy($image);//释放图片
         break;
     }
 }

/**
* desription 判断是否gif动画
* @param sting image_file图片路径
* @return boolean t 是 f 否
*/

private function check_gifcartoon($image_file){
$fp = fopen($image_file,'rb');
$image_head = fread($fp,1024);
fclose($fp);
return preg_match("/".chr(0x21).chr(0xff).chr(0x0b).'NETSCAPE2.0'."/",$image_head)?false:true;

}

在安装fastadmin后,这是进入网站首页是可以正常访问的!

但是访问后台时会发现报错错404

解决:

1、这个时候需要找到nginx下对应的的php配置文件,把第一行注释掉就可以了。
2、然后把第一行注释掉
3、然后就可以访问了

1、

2、

3、

有时候我们更新composer的时候,在安装插件时会有php的版本要求,例如:

此时插件要求php版本要大于等于php7.4,但是本地php配置环境是php7.3,这个时候不需要切换环境变量的php版本也可以根据场景需要的php版本来更新composer
使用方法:php版本目录 composer目录 update -vvv
例如下图:

(备注:composer也是要指定目录的,直接使用D:\BtSoft\php\74\php.exe composerr update -vvv 是不行的)

正常添加反向代理配置

谷歌浏览器能正常打开页面

但是火狐打不开,解决:

将这个配置删除

### PHP 自动加载功能的由来 在 PHP 开发过程中,如果希望从外部引入一个 Class ,通常会使用 include 和 require 方法。这个在小规模开发的时候,没什么大问题。但在大型的开发项目中,使用这种方式会带来一些隐含的问题: - 如果一个 PHP 文件需要使用很多其它类,那么就需要很多的 require/include 语句,这样有可能会 造成遗漏 或者 包含进不必要的类文件。 - 不方便管理。 - 文件多消耗性能 PHP5 为这个问题提供了一个解决方案,这就是 类的自动加载(autoload)机制。autoload机制 可以使得 PHP 程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为 Lazy loading (惰性加载)。 ### 自动加载功能优点: - 使用类之前无需 include / require - 使用类的时候才会 include / require 文件,实现了 lazy loading ,避免了 include / require 多余文件。 - 无需考虑引入 类的实际磁盘地址 ,实现了逻辑和实体文件的分离。 ### PHP 自动加载函数 __autoload() 从 PHP5 开始,当我们在使用一个类时,如果发现这个类没有加载,就会自动运行 __autoload() 函数,这个函数是我们在程序中自定义的,在这个函数中我们可以加载需要使用的类。下面是个简单的示例 原文链接:https://segmentfault.com/a/1190000014948542