## 常见技巧目录
[TOC=2,3]
* * * * *
- ### SQL技巧
* * * * *
>[info]#### 解决方案
~~~
1)查找pnum字段中包含3或者9的记录
使用函数find_in_set:SELECT * FROM test WHERE find_in_set('3',pnum) OR find_in_set('9',pnum);
使用正则REGEXP:SELECT * FROM test WHERE pnum REGEXP '(3|9)';
SELECT GROUP_CONCAT(send_no SEPARATOR \"','\") send_no_str FROM stock_receive_extend where FIND_IN_SET('{$params['express_track_no']}',express_track_no) LIMIT 1
~~~
- ### AJAX跨域
* * * * *
>[info]#### 解决方案
~~~
//如果需要设置允许所有域名发起的跨域请求,可以使用通配符 *
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT,POST,GET,DELETE,OPTIONS");
header("Access-Control-Allow-Headers:Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
if($_SERVER['REQUEST_METHOD']=='OPTIONS'){
header("HTTP/1.1 200 OK");
exit();
}
~~~
- ### 前面补0三位显
* * * * *
>[info]#### 解决方案1
~~~
echo substr(strval(1+1000),2,2);
~~~
>[info]#### 测试结果
~~~
001
~~~
>[info]#### 解决方案2
~~~
echo str_pad(1,3,"0",STR_PAD_LEFT);
~~~
>[info]#### 测试结果
~~~
001
~~~
- ### Thinkphp中在开启缓存情况下解决局部不缓存
* * * * *
>[info]#### 解决方案
~~~
1)采用ajax方法可实现局部不缓存问题
~~~
- ### 多条件查询页面刷新或者返回查询条件
* * * * *
>[info]#### 解决方案1
~~~
1)将查询条件URL保存到cookie中(推荐)
setcookie("backurl",$_SERVER['REQUEST_URI']);
$_COOKIE['backurl'] = $_SERVER['REQUEST_URI'];(也可以)
2)在前端获取到cookie中的URL地址,当返回/刷新时用重定向到此URL地址
<?php
if(isset($_COOKIE['backurl'])){
$backurl=$_COOKIE['backurl'];
}else{
$backurl='/stocks/index';
}
?>
3)前段查询条件,通过模板取参数值。
注:URL中的参数,是上一次使用的查询条件
~~~
>[info]#### 解决方案2
~~~
1)将查询条件URL保存到session中(不建议,消耗服务器资源)
setcookie("backurl",$_SERVER['REQUEST_URI']);
$_COOKIE['backurl'] = $_SERVER['REQUEST_URI'];(也可以)
其余步骤同上。
~~~
- ### 数据库字段type为0和1时,0和空字符串混淆的处理方法
* * * * *
>[info]#### 解决方案
~~~
1)控制器正常接收数据包括0,空,1
$params['type'] = addslashes($_REQUEST['type']);
2)在模型哪里判断并拼接查询条件(排除空字符串这种)
if( $params['type']==='0'||$params['type']==='1'){
$where .= " AND `type`=".$params['type'];
}
~~~
- ### 将数组转换成字符串,并用单引号隔开(适用于where in 查询条件)
* * * * *
>[info]#### 解决方案
~~~
$serial_no 数组
$serial_no_str = "'".str_replace(",","','",implode(',', $serial_no))."'";//内部单号字符串
$serial_no_str = "'". implode("', '", $serial_no) ."'";;//内部单号字符串
~~~
- ### 分批量的从数据库循环读取数据
* * * * *
>[info]#### 解决方案
~~~
<?php
$read = ture;
$limit = 0;
$size = 10;
while($read)
{
$sql = "select id,name from table limit {$limit},{$size}";
$data = $db->select($sql);
//todo 你的业务逻辑
if(!data)
{
$read = false;
break;数据为空,直接停止了循环
}
$limit += $size ;每次获取后面5条,直至数据查询为空.
}
~~~
- ### 判断是否是AJAX
* * * * *
>[info]#### 解决方案
~~~
<?php
if(isset($_SERVER["HTTP_X_REQUESTED_WITH"]) && strtolower($_SERVER["HTTP_X_REQUESTED_WITH"])=="xmlhttprequest"){
// ajax 请求的处理方式
}else{
// 正常请求的处理方式
};
~~~
- ### 判断多个空格的变量是否为空
* * * * *
>[info]#### 解决方案
~~~
$a=' ';
if(!empty($a)&&!ctype_space($a)){
echo "变量不为空";
}else
echo "变量为空";
~~~
- ### 判断多维数组是否为空
* * * * *
>[info]#### 解决方案
~~~
$a=array(array(),array());
if(count(array_filter($a))>0){
echo "不为空";
}else
echo "为空";
$sheetDatas = array_filter($sheetData, function ($value){
return array_filter($value);
});
~~~
- ### PHP执行是否限制
* * * * *
>[info]#### 解决方案
~~~
header("Content-type: text/html; charset=utf-8");
ignore_user_abort(true);
set_time_limit(0);
ini_set('memory_limit', '1024M');
~~~
- ### PHP去除换行、空行、行首行尾空格逗号、中间中英文空格
* * * * *
>[info]#### 解决方案
~~~
str_replace(array(" "," ","\n","\r","\t"), array("","","","",""), rtrim(trim($str),','));
~~~
- ### CI获取某个表所有字段名
* * * * *
>[info]#### 解决方案
~~~
/**
* @desc 获取某个表所有字段名
* @author ityangs 2017-11-23
* @param $table string 表名
*/
function get_table_all_column($table)
{
$sql = " select COLUMN_NAME as `tcolumn` from information_schema.COLUMNS where ".
" table_name = '{$table}' and table_schema = '{$this->db->database}' ";
$query = $this->db->query($sql);
return array_column($query->result_array(),'tcolumn');
}
~~~
- ### SOAP远程调用接口
* * * * *
>[info]#### 解决方案
~~~
1)生成SOAP客户端对象
$this->wsdl='';
/**
* 生成SOAP对象 SoapClient
* @date: 2017年12月14日 下午7:53:42
* @author: ityangs<ityangs@163.com>
*/
protected function getSoap(){
$mode = array(
'soap_version' => 'SOAP_1_1', // use soap 1.1 client
'trace' => 1,
'encoding'=>'UTF-8',
'connection_timeout'=>120
);
if(empty($this->soap)){
$this->soap = new SoapClient ($this->wsdl, $mode);
}
return $this->soap;
}
2)访问接口
$this->soap->__getFunctions()//获取服务端方法名称
$this->soap->__getTypes()//获取服务端方法参数名
调用
try{
方法一:
$params = array('in0'=>json_encode($postData));
$responseData = $this->soap->__soapCall('queryTrackingData',array($params));
方法二:
$params = array('in0'=>json_encode($postData));
$responseData = $this->soap->__soapCall('queryTrackingData',array($params));
方法三:
$params = array('in0'=>json_encode($postData));
$responseData = $this->soap->queryTrackingData($params);
}catch(soapFault $e){
throw new Exception($e->getMessage(),400);
}
~~~
- ### 循环A-Z当超过26个字母时输出AA,AB,AC
* * * * *
>[info]#### 解决方案
~~~
for ($i = 0; $i < $templateTitleTotal; $i ++) {
$y = ($i / 26);
if ($y >= 1) {
$y = intval($y);
$column = chr($y + 64) . chr($i - $y * 26 + 65);
} else {
$column = chr($i + 65);
}
echo $column;
}
~~~
- ### AJAX 导入文件
* * * * *
>[info]#### 解决方案
~~~
//导入按钮
$('.import_btn').click(function(){
var formData = new FormData();
formData.append("logistics", document.getElementById("logistics").files[0]);
var load=layer.load(1);
$.ajax({
url: "/order/index/import-change-logistics",
type: "POST",
data: formData,
dataType:"JSON",
contentType: false,
processData: false,
success: function (data) {
layer.close(load);
layer.msg(data.msg,{icon:data.status});
if(data.status == '1'){
window.location.reload();
}
}
});
})
});
//对于flash不兼容情况
$("#upload_picture_btn").click(function () {
var fileObj = document.getElementById("upload_picture").files[0]; // js 获取文件对象
if (typeof (fileObj) == "undefined" || fileObj.size <= 0) {
alert("请选择图片");
return;
}
var formFile = new FormData();
formFile.append("download", fileObj); //加入文件对象
$.ajax({
url: "{:U('File/uploadPicture',array('session_id'=>session_id()))}",
data: formFile,
type: "Post",
dataType: "json",
cache: false,//上传文件无需缓存
processData: false,//用于对data参数进行序列化处理 这里必须false
contentType: false, //必须
success: function (data) {
console.log(data);
if(data.status){
$("#upload_picture_name").val(data.name);
$("#upload_picture_rel_name").val(data.savename);
$("#upload_picture_url").val(data.path);
src = data.url || '__ROOT__' + data.path
$("#upload_picture_name").parent().find('.upload-img-box').html(
'<div class="upload-pre-item"><img src="' + src + '"/></div>'
);
}
},
});
});
</script>
导入的文件信息:
<pre>Array
(
[logistics] => Array
(
[name] => s.xlsx
[type] => application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
[tmp_name] => C:\Windows\Temp\php6EBB.tmp
[error] => 0
[size] => 8829
)
)
</pre>
验证上传文件:
if (empty($_FILES['logistics']['name'])){
echo json_encode(array('status'=>0,'msg'=>'请选择要导入的文件!'));
exit;
}
$tmp_file = $_FILES['logistics'] ['tmp_name'];
$file_types = explode ( ".", $_FILES['logistics']['name'] );
$file_type = $file_types [count( $file_types ) - 1];
/*判别是不是.xls文件,判别是不是excel文件*/
if (strtolower($file_type) != "xls"){
echo json_encode(array('status'=>0,'msg'=>'导入失败!文件格式不正确!(请使用xls格式文件)'));
exit;
}
/*设置上传路径*/
$savePath = '../public/upload/xlsx/'.date('Y').'/'.date('m').'/'.date('d').'/';
if ( !file_exists( $savePath ) ){
mkdir($savePath,0755,true);
}
/*以时间来命名上传的文件*/
$str = date ( 'Ymdhis' );
$file_name = $str . "." . $file_type;
if(!move_uploaded_file($tmp_file, $savePath . $file_name)){
echo json_encode(array('status'=>0,'msg'=>'上传失败!'));
exit;
}
~~~
- ### 保留搜索框查询条件
* * * * *
>[info]#### 解决方案
Cookie实现:(后端)
~~~
1)将参数封装成连接
$path = "/index.php?c=package&m=shipping_fee_abnormal_index";
$path = $this->get_page_path($path,$params);
/**
* 分页设置(获取地址)
*/
function get_page_path($path,$params){
if(!is_array($params) || empty($params)) return $path;
foreach($params as $k=>$v){
if($v != '' && !is_array($v) ){
$path .= "&".$k."=".$v;
}else if( $v != '' && is_array($v) ){
foreach( $v as $key=>$val ){
$path .= "&".$k."[]=".$val;
}
}
}
return $path;
}
2)保存到cookie中
setcookie('shipping_fee_abnormal_index_url',$path, time()+3600, strtolower('/'.__CLASS__));//保存返回URL
3)获取cookie链接地址
$backURL='/change_stock_express/change_stock';
if($_COOKIE['shipping_fee_abnormal_index_url']){
$backURL=$_COOKIE['shipping_fee_abnormal_index_url'];
}
~~~
- ### PHP多维数组根据某个字段排序
* * * * *
>[info]#### 解决方案
~~~
$down_barcode_log_arr=
Array
(
[0] => Array
(
[operator] => yj
[operator_time] => 2018-01-18 18:13:21
[filepath] => uploads/ed_213505103_124barcode.zip
)
[1] => Array
(
[operator] => yj
[operator_time] => 2018-01-18 18:13:18
[filepath] => uploads/ed_213505103_124barcode.zip
)
)
//跟据操作时间降序排序
array_multisort(array_column($down_barcode_log_arr, 'operator_time'),SORT_DESC,$down_barcode_log_arr);
~~~
- ### 保留小数位并进位round/sprintf/number_format
* * * * *
>[info]#### 解决方案
~~~
$num = 1012336644448.4567646846;
//第一种:利用round()对浮点数进行四舍五入
echo round(448.4567646846,2); //448.46
echo "<br>";
echo round($num,2); //1012336644448.5
echo "<br>";
//第二种:利用sprintf格式化字符串
echo sprintf("%.3f",$num);//1,012,336,644,448.457
echo "<br>";
//第三种:利用千位分组来格式化数字的函数number_format()
echo number_format($num, 3); //1,012,336,644,448.457
echo "<br>";
//或者如下
echo number_format($num, 3, '.', '|'); //1|012|336|644|448.457
echo "<br>";
echo number_format($num, 3, '.', ''); //1012336644448.457
echo "<br>";
echo number_format("2040",4); //2,040.0000
echo number_format("2040",4,".","");//2040.0000
~~~
- ### JQuery遍历json数组对象并弹出框显示
* * * * *
>[info]#### 解决方案
~~~
$(function () {
var tbody = "";
var obj = [{ "name": "项海军", "password": "123456"}];
//下面使用each进行遍历
$.each(obj, function (n, value) {
var trs = "";
trs += "<tr><td>" + value.name + "</td> <td>" + value.password + "</td></tr>";
tbody += trs;
});
$("#project").append(tbody);
});
EG:
<script type="text/javascript">
$(document).ready(function(){
//查看
$('.detail').click(function() {
var id = $('#id').val();
$.ajax({
type: "POST",
async:false,
dataType:'json',
url: "/update_compare_log/getDetailLog",
data: "id="+id,
success: function(data){
if(data.status==400){
alert(data.message);
}else{
var obj=data.data;
var table = '<table class="owners_table">';
table+='<tr><th>序号</th><th>更新字段</th><th>更新前</th><th>更新后</th></tr>';
$.each(obj, function (n, value) {
table+="<tr><td>"+(++n)+"</td><td>"+value.field+"</td><td>"+value.before_val+"</td><td>"+value.after_val+"</td></tr>";
});
table+='</table>';
showStr(table);
}
}
});
})
});
function showStr(str){
layer.open({
type: 1,
skin: 'layui-layer-rim', //加上边框
area: ['800px', '600px'], //宽高
content: str
});
}
</script>
EG2:
<style type="text/css">
.none {
display: none;
}
</style>
<td class="none id-js"><?php echo $val['id'];?></td>
<script src="<?php echo base_url().'www/'.config_item('template');?>/js/layer-v1.7.0/jquery-1.7.2.js"></script>
<script type="text/javascript" src="<?php echo base_url().'www/'.config_item('template');?>/js/layer/layer.js"></script>
<script type="text/javascript">
//查看
$('.detail').mouseover(function() {
var id = $(this).closest('tr').find('.id-js').text();
var remain_box_num = $(this).closest('tr').find('.detail').text();
if(remain_box_num==0){
return false;
}
$.ajax({
type: "POST",
async:false,
dataType:'json',
url: "/loading_tasks/getDetailRemainBox",
data: "id="+id,
success: function(data){
if(data.status==400){
alert(data.message);
}else{
var obj=data.data;
var table = '<table class="owners_table">';
table+='<tr><th>序号</th><th>箱号</th>';
$.each(obj, function (n, value) {
table+="<tr><td>"+(++n)+"</td><td>"+value.case_number+"</td></tr>";
});
table+='</table>';
showStr(table);
}
}
});
})
function showStr(str){
layer.open({
type: 1,
skin: '', //加上边框
area: ['200px', '300px'], //宽高
content: str
});
}
</script>
~~~
- ### JS判断是否是NULL
* * * * *
>[info]#### 解决方案
~~~
var exp = null;
if (!exp && typeof exp != "undefined" && exp != 0)
{
alert("is null");
}
typeof exp != "undefined" 排除了 undefined;
exp != 0 排除了数字零和 false。
更简单的正确的方法:
var exp = null;
if (exp === null)
{
alert("is null");
}
~~~
- ### JS 过滤数组中的空值
* * * * *
>[info]#### 解决方案
~~~
/**
* es6语法
* 过滤JS数组中的空值,假值等(es6语法)
* @param array 需要过滤的数组
* @returns {Array} []
*/
function filter_array(array) {
return array.filter(item=>item);
}
~~~
- ### CSS3垂直居中
* * * * *
>[info]#### 解决方案
~~~
在CSS3垂直居中方法如下:
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
~~~
- ### 先解码后转码(utf-8)
* * * * *
>[info]#### 解决方案
~~~
iconv("gb2312","utf-8",urldecode($val['name']))
~~~
- ### JS: json对象与json字符串互转
* * * * *
>[info]#### 解决方案
~~~
例如:
JSON字符串:
var str1 = '{ "name": "xx", "sex": "man" }';
JSON对象:
var obj = { "name": "xx", "sex": "man" };
字符串转对象:
var obj = JSON.parse(str); //由JSON字符串转换为JSON对象
对象转字符串:
var str = JSON.stringify(obj); //由JSON字符串转换为JSON对象
~~~
- ### 判断当前浏览器是否是IE
* * * * *
>[info]#### 解决方案
~~~
<!--[if IE 6]>仅IE6可识别<![endif]-->
<!--[if lte IE 6]> IE6及其以下版本可识别<![endif]-->
<!--[if lt IE 6]> IE6以下版本可识别<![endif]-->
<!--[if gte IE 6]> IE6及其以上版本可识别<![endif]-->
<!--[if gt IE 6]> IE6以上版本可识别<![endif]-->
<!--[if IE]> 所有的IE可识别<![endif]-->
<!--[if !IE]><!--> 除IE外都可识别<!--<![endif]-->
~~~
- ### preg_match正则匹配HTTP/HTTPS
* * * * *
>[info]#### 解决方案
~~~
preg_match("/^(http:\/\/|https:\/\/).*$/",$url,$match);
~~~
- ### preg_replace去除所有空格
* * * * *
>[info]#### 解决方案
~~~
preg_replace('# #', '', $zipCode);//去除所有空格
~~~
- ### mysql 数据库中时间,取前后几秒 几分钟 几小时 几天
* * * * *
>[info]#### 解决方案
~~~
取当前时间:
select current_timestamp;
输出:2016-06-16 16:12:52
select now();
输出:2016-06-16 16:12:52
取当前时间的前一分钟:
select SUBDATE(now(),interval 60 second);
输出:2016-06-16 16:11:52
取当前时间的下一分钟:
select ADDDATE(now(),interval 60 second);
输出:2016-06-16 16:13:52
通过变化上面的单位。可以取前后 分钟,小时,天的时间
取前一分钟的时间:
select SUBDATE(now(),interval 1 minute);
输出:2016-06-16 16:16:38
取前一小时的时间:
select SUBDATE(now(),interval 1 hour);
输出:2016-06-16 15:17:38
取前一天的时间:
select SUBDATE(now(),interval 1 day);
输出:2016-06-15 16:17:38
###########################
取后一分钟的时间:
select ADDDATE(now(),interval 1 minute);
输出:2016-06-16 16:17:38
取后一小时的时间:
select ADDDATE(now(),interval 1 hour);
输出:2016-06-16 17:17:38
取后一天的时间:
select ADDDATE(now(),interval 1 day);
输出:2016-06-17 16:17:38
~~~
- ### JS屏蔽右键保存下载
* * * * *
>[info]#### 解决方案
~~~
document.onkeydown=function(){
var e = window.event||arguments[0];
if(e.keyCode==123){
alert('请尊重劳动成果!www.xx.com');
return false;
}else if((e.ctrlKey)&&(e.shiftKey)&&(e.keyCode==73)){
alert('请尊重劳动成果!www.xx.com');
return false;
}else if((e.ctrlKey)&&(e.keyCode==85)){
alert('请尊重劳动成果!www.xx.com');
return false;
}else if((e.ctrlKey)&&(e.keyCode==83)){
alert('请尊重劳动成果!www.xx.com');
return false;
}
}
document.oncontextmenu=function(){
alert('请尊重劳动成果!www.xx.com');
return false;
}
~~~
- ### 常见的js数组对象操作
* * * * *
>[info]#### 解决方案
~~~
1)将数组对象中某一列转化成数组
const tempTableArr=tempTableDatasArrObj.map(item=>item['goodId']);
2)forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
let tableData=[];
searchTableDatas.forEach(data => {
if(!tempTableArr.include(data['goodId'])){
tableData.push(data)
}
});
3)验证数组中是否存在该值
tempTableArr.include(data['goodId']))
4) ES6中数组去重
const array = ['🐑', 1, 2, '🐑','🐑', 3];
Array.from(new Set(array));
~~~