本文是使用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;
}
}
当前使用的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);
}
File -> Invalidate Caches/Restart
原文链接:https://blog.csdn.net/qq_36025814/article/details/128513733
要将 MySQL 数据库中某个表中的某个字段值从小写转换为大写,可以使用以下 SQL 更新语句:
UPDATE your_table_name SET your_field_name = UPPER(your_field_name);
请将 your_table_name
替换为你的表名,your_field_name
替换为你需要转换的字段名。执行该语句后,将会将该字段中所有的小写字符串转换为大写字符串。
注意,执行该 SQL 更新语句会永久修改数据库表中的数据,请谨慎操作,并在执行前先备份数据库。
为了保证前后端接口的兼容性,通常需要对接口进行版本管理。以下是一些示例常用的接口版本管理的方法:
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 版本用户端实现逻辑
}
}
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 {
// 其他版本的用户端实现逻辑
}
}
}
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
命令将指定的提交合并到主分支。
具体步骤如下:
git checkout main
git log --oneline <dev-branch>
其中,<dev-branch>
是开发分支的名字。
找到想要合并的提交的 ID,复制它。
将复制的提交 ID 应用到主分支中:
git cherry-pick <commit-id>
其中,<commit-id>
是刚刚复制的提交 ID。
git add <冲突文件> # 添加已解决冲突的文件
git cherry-pick --continue # 继续进行 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 count
和 as 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::getId
和 Person::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());
}
}
在这个基类中,我们定义了一些通用的方法,例如:
这些方法被定义为公共方法,因此可以在具体的控制器中进行继承和重写,以进行必要的定制和扩展。同时,由于这些方法被封装在基类中,因此可以减少控制器中的重复代码,提高代码的复用性和可维护性。
├── 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.java
和HomeController.java
两个控制器文件,分别用于处理用户和主页的请求。
dto
目录下包含了用于数据传输的UserDTO.java
和ErrorResponseDTO.java
两个文件。
entity
目录下包含了实体对象User.java
。
exception
目录下包含了用于异常处理的CustomException.java
、BadRequestException.java
和ResourceNotFoundException.java
三个文件。
mapper
目录下包含了UserMapper.java
文件,用于对象转换。
repository
目录下包含了UserRepository.java
文件,用于数据的增删改查。
service
目录下包含了UserService.java
和UserServiceImpl.java
两个文件,用于业务逻辑处理。
util
目录下只添加了一个CommonUtils.java
文件,用于放置一些通用的工具类。
vo
目录下包含了UserVO.java
和ResponseVO.java
两个文件,分别用于值对象和响应对象。
在resources
目录下,application.properties
文件用于配置应用程序的一些属性,例如数据库连接等;logback.xml
文件是logback日志的配置文件;static
目录用于存放静态资源文件;templates
目录下是用于存放模板文件。
README.md
文件是项目说明文档,而.gitignore
文件则是用于配置git版本控制中需要忽略的文件列表。LICENSE
文件用于定义代码版权等相关信息。
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、声明返回类型
有时候我们需要修改数组的键名,比如获取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);
}
安装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版本
使用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
取绝对值
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;
}
}
/**
* 采用递归将数据列表转换成树
*
* @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- ./?%&=])?
方法一
git branch --set-upstream-to=origin/<远程分支> <本地分支>
方法二
git push -u origin <远程分支>
WordPress Shortcode 指的是一些使用[]包含的短代码,WordPress会识别这些短代码并根据短代码的定义输出特定的内容。
Shortcode API 支持几乎所有可能的组合形式:自关闭标签,开放标签,含有参数的标签等。
[mycode]
[mycode foo="bar" ]
[mycode]Some Content(支持html)[/mycode] //包含内容
[mycode]Content [another-shotcode] more content[/mycode] //嵌套
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
有时候需要根据用户访问的设备类型进行相应的处理
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;
}
在我们平时程序当中,如果字符串中出现了控制字符,json_decode 和 simplexml_load_string 这些函数就会失败
控制字符(Control Character),或者说非打印字符,出现于特定的信息文本中,表示某一控制功能的字符,如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通讯专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等。
具体控制字符一共有下面两个集合:
preg_replace('/[\x00-\x1F\x7F-\x9F]/u', '', $str);
composer require phpoffice/phpexcel
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');
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);
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次幂
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_encode($data);//对变量进行JSON编码
json_decode($data,true)//对JSON格式的字符串进行解码
json_last_error();//返回最后一次反生的错误
serialize()//返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。
unserialize()//对单一的已序列化的变量进行操作,将其转换回 PHP 的值。
json_encode($data);//对变量进行JSON编码
json_decode($data,true)//对JSON格式的字符串进行解码
json_last_error();//返回最后一次反生的错误
//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
$subject = "abcdef";
$pattern = '/^def/';
$result = preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
//$result 返回0或者1
//$matches 匹配结果
$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]为匹配每一个括号中的第二项)
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);
//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()
$time = time();
echo date_format($time,"Y/m/d H:i:s");
echo date("Y/m/d H:i:s",$time);
$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; //
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;
$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()
$time = time();
echo date_format($time,"Y/m/d H:i:s");
$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; //
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;
$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;
}
有时候我们更新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 是不行的)
正常添加反向代理配置
谷歌浏览器能正常打开页面
但是火狐打不开,解决:
将这个配置删除