年度归档: 2016 年

  • nginx服务器http重定向到https 图文教程

    nginx服务器http重定向到https 图文教程

    老季博客刚刚启用了ssl,下面我们贴一个最新的将http重定向到https的最新支持的写法:

    server {
        listen 80 default_server;
        server_name    laoji.org;
        return 301 https://$server_name$request_uri;
    }
    server {
        listen 443 ssl;
        server_name    laoji.org;
        [....]
    }

    官方文档:

    http://wiki.nginx.org/Pitfalls#Taxing_Rewrites

  • ThinkPHP Where 条件中使用表达式

    ThinkPHP Where 条件中使用表达式

    前面我们介绍了,ThinkPHP View视图 模板使用实例总结,下面我们总结一下ThinkPHP中mysql数据库查询时Where条件表达式的写法。

    Where 条件表达式格式为:

    $map['字段名']  = array('表达式', '操作条件');
    

    其中 $map 是一个普通的数组变量,可以根据自己需求而命名。上述格式中的表达式实际是运算符的意义:

    ThinkPHP运算符 与 SQL运算符 对照表
    TP运算符SQL运算符例子实际查询条件
    eq=$map[‘id’] = array(‘eq’,100);等效于:$map[‘id’] = 100;
    neq!=$map[‘id’] = array(‘neq’,100);id != 100
    gt>$map[‘id’] = array(‘gt’,100);id > 100
    egt>=$map[‘id’] = array(‘egt’,100);id >= 100
    lt<$map[‘id’] = array(‘lt’,100);id < 100
    elt<=$map[‘id’] = array(‘elt’,100);id <= 100
    likelike$map<‘username’> = array(‘like’,’Admin%’);username like ‘Admin%’
    betweenbetween and$map[‘id’] = array(‘between’,’1,8′);id BETWEEN 1 AND 8
    not betweennot between and$map[‘id’] = array(‘not between’,’1,8′);id NOT BETWEEN 1 AND 8
    inin$map[‘id’] = array(‘in’,’1,5,8′);id in(1,5,8)
    not innot in$map[‘id’] = array(‘not in’,’1,5,8′);id not in(1,5,8)
    and(默认)and$map[‘id’] = array(array(‘gt’,1),array(‘lt’,10));(id > 1) AND (id < 10)
    oror$map[‘id’] = array(array(‘gt’,3),array(‘lt’,10), ‘or’);(id > 3) OR (id < 10)
    xor(异或)xor两个输入中只有一个是true时,结果为true,否则为false,例子略。1 xor 1 = 0
    exp综合表达式$map[‘id’] = array(‘exp’,’in(1,3,8)’);$map[‘id’] = array(‘in’,’1,3,8′);

    补充说明

    • 同 SQL 一样,ThinkPHP运算符不区分大小写,eq 与 EQ 一样。
    • between、 in 条件支持字符串或者数组,即下面两种写法是等效的:
      $map['id']  = array('not in','1,5,8');
      $map['id']  = array('not in',array('1','5','8'));
      

    exp 表达式

    上表中的 exp 不是一个运算符,而是一个综合表达式以支持更复杂的条件设置。exp 的操作条件不会被当成字符串,可以使用任何 SQL 支持的语法,包括使用函数和字段名称。

    exp 不仅用于 where 条件,也可以用于数据更新,如:

    $Dao = M("Article");
    // 构建 save 的数据数组,文章点击数+1
    $data['id'] = 10;
    $data['counter'] = array('exp','counter+1');
    // 根据条件保存修改的数据
    $User->save($data);
  • Mysql 表崩溃后Crashed 自动修复备份数据库 Shell 脚本

    Mysql 表崩溃后Crashed 自动修复备份数据库 Shell 脚本

    前面我们写了Linux 自动备份Mysql Shell 脚本,但是最近论坛被疯狂灌水,导致一些表崩溃Crashed了,所以我们mysqldump的时候会报错,以下脚本将会先检查数据库里所有的表(如果有问题将自动执行修复动作),然后再自动备份整个数据库。

    #!/bin/sh 
    d=`date "+%Y-%m-%d-%H-%M-%S"` 
    v_user="数据库用户名" 
    v_password="密码" 
    v_database="数据库名"
    #开始repair整个数据库里的表,如果-r 修复不了,可以用-o 参数代替修复
    mysqlcheck -u$v_user -p$v_password $v_database -r > /root/RepairLog/$d.log
    # 以下是自动备份脚本动作
    mysqldump -u$v_user -p$v_password $v_database --default-character-set=gbk | gzip > $FP$FName.sql.gz   


    加入自动运行之前可以先运行测试一下是否有报错:
    sh /backup/sqlDump.sh

    crontab 定时任务:

    如果没有问题的话然后加入到crontab里

    crontab -e

    内容如下:

    30 3 * * 1 sh /backup/sqlDump.sh

    每个星期一的早上3:30 自动进行备份。

  • Chrome一直提示“adobe flash player 因过期而遭阻止”  解决方法 图文教程

    Chrome一直提示“adobe flash player 因过期而遭阻止” 解决方法 图文教程

    最近在更新了Chrome浏览器之后,提示 adobe flash player 已过期的问题,反复提示,从网上也找了很多办法都没有解决。这里给大家提供一个最完美的解决方案。经亲自测试,完美解决adobe flash player插件过期遇到阻止的问题.

    20161111204746
    Chrome一直提示“adobe flash player 因过期而遭阻止” ,解决方法 图文教程

    1. 下载:在百度搜索 ” adobe flash player ppapi “,去官方网站下载完成安装。

      直达地址:http://labs.adobe.com/downloads/flashplayer.html

    2. 下载对应操作系统的PPAPI版本,安装,然后重启浏览器,完成。

      Chrome一直提示“adobe flash player 因过期而遭阻止”
      Chrome一直提示“adobe flash player 因过期而遭阻止”

      Windows 32-bit 64 bit 安装直达链接:https://fpdownload.macromedia.com/pub/labs/flashruntimes/flashplayer/install_flash_player_ppapi.exe

    3. 目前网络上流传的几种方法其实并不能完美解决问题:

      1,浏览器地址栏输入 chrome://plugins 停用过期的 flash player插件,相当于没解决问题;

      2,更新chrome浏览器,其实这个办法很多人都懂,但是也没有用;

      3,下载更新adobe flash player插件,没用!

      4,下载官方adobe flash player 安装更新,试过都知道没用;

      5,Chrome.exe快捷方式加上指令“ –allow-outdated-plugins”不行;

      其实问题的本质在于,Chrome支持的是PPAPI版本,而不是NPAPI版本或者ActiveX;本人试了N多办法,最终完美解决这个问题,写出来希望对大家有帮助。

  • Underscore.js 学习笔记 template for each map reduce find filter 实例

    Underscore.js 学习笔记 template for each map reduce find filter 实例

    项目用了很久underscore.每次都是临时查手册,没有系统的研究过,最近有空正好看看

    github地址:https://github.com/lily1010/underscore_learn

     

    一 Underscore定义

    一个JavaScript实用库,提供了一整套函数式编程的实用功能,但是没有扩展任何JavaScript内置对象,它是Backbone重度依赖的js库.主要涉及对Collection、Object、Array、Function的操作.

     

    二 _.each

    (1)定位:遍历list中的所有元素,按顺序用遍历输出每个元素,不返回任何值.

    (2)标准模式:_.each(list, iteratee, [context]),其中[context]是迭代器的上下文,也就是迭代器中this的指向

    (3)如果数据list是数组,iteratee的参数:(element, index, list)

    (4)如果数据list是对象,iteratee的参数是(value, key, list)

    (5)如果存在原生的forEach方法,Underscore就使用它代替

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>underscore--each函数</title>
            <script src="../js/underscore.js"></script>
        </head>
        <body>
            <script type="text/javascript">
                // 遍历数组 (可获取三个参数element, index, list)
                var data = [1,2,3];
                _.each(data,function(element, index, list) { //三个参数都是可选,位置固定,element是数组值,index是值在数组位置,list是整个数组
                    document.write(element);    //打印出1 2 3
                    document.write(index);        //打印出0 1 2
                    document.write(list);        //打印出1,2,3 1,2,3 1,2,3,因为每次遍历都会打印一遍
                });
                
                // 遍历对象 (可获取三个参数 value,key,list)
                var data2 = {
                    name1: "lili",
                    name2: "manman"
                };
                _.each(data2,function(value,key,list) {   //注意第一个是value,第二个是key,位置固定,但参数可以缺少
                    document.write(value);   //打印出lili manman
                    document.write(key);    //打印出name1 name2
                    document.write(list);  //打印出 [object Object] [object Object] ,因为循环了两边,故打印两遍
                });
            
                // 标准格式  _.each(list, iteratee, [context]) ,其中[context]是迭代器的上下文,也就是迭代器中this的指向
                var obj = {name: "hello"};  
                _.each([1, 2, 3], function (i) { 
                  document.write(this.name + ":" + i); 
                }, obj); 
            </script>
        </body>
    </html>

    三 _.map

    (1)定位:通过转换函数(iteratee迭代器)映射列表中的每个值,将返回的值依次存入一个新的数组.

    (2)标准模式:_.map(list, iteratee, [context]),其中[context]是迭代器的上下文,也就是迭代器中this的指向.

    (3)如果数据list是数组,iteratee的参数:(element, index, list)

    (4)如果数据list是对象,iteratee的参数是(value, key, list)

    (5)用法同each,但是它返回的是数组

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>underscore--map函数</title>
            <script src="../js/underscore.js"></script>
        </head>
        <body>
            <script type="text/javascript">
                // 遍历数组后生成数组 (可获取三个参数element, index, list)
                var data = [1,2,3];
                _.map(data,function(element, index, list) { //三个参数都是可选,位置固定,element是数组值,index是值在数组位置,list是整个数组
                    document.write(element);    //打印出[1,2,3]
                    document.write(index);        //打印出0 1 2
                    document.write(list);        //打印出1,2,3 1,2,3 1,2,3,因为每次遍历都会打印一遍
                });
                
    //            // 遍历对象 (可获取三个参数 value,key,list)
                var data2 = {
                    name1: "lili",
                    name2: "manman"
                };
                _.map(data2,function(value,key,list) {   //注意第一个是value,第二个是key,位置固定,但参数可以缺少
                    document.write(value);   //打印出lili manman
                    document.write(key);    //打印出name1 name2
                    document.write(list);  //打印出 [object Object] [object Object] ,因为循环了两边,故打印两遍
                });
            
                // 标准格式  _.map(list, iteratee, [context]) ,其中[context]是迭代器的上下文,也就是迭代器中this的指向
                var obj = {name: "hello"};  
                _.each([1, 2, 3], function (i) { 
                  document.write(this.name + ":" + i); 
                }, obj); 
            </script>
        </body>
    </html>

    四 _.reduce

    (1)标准模式:reduce_.reduce(list, iterator, memo, [context])

    (2)这里不做深入探讨,参数太多,感兴趣的去官网看一下

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>underscore--reduce函数</title>
            <script src="../js/underscore.js"></script>
        </head>
        <body>
            <script type="text/javascript">
                // 遍历数组
                var data = [1,2,3];
                _.reduce(data,function(memo, element, index, list) { //四个参数都是可选,位置固定,memo是设置一个初始值,element是数组值,index是值在数组位置,list是整个数组
                    document.write(memo);   //打印出 4 undefined undefined
                    document.write(element);    //打印出[1,2,3]
                    document.write(index);        //打印出0 1 2
                    document.write(list);        //打印出1,2,3 1,2,3 1,2,3,因为每次遍历都会打印一遍
                },4);   //注意4就是参数memo
            </script>
        </body>
    </html>

    五 _.find函数

    (1)标准写法:_.find(list, predicate, [context])

    (2)在list中逐项查找,返回第一个通过predicate迭代函数真值检测的元素值.

    (3)如果没有值传递给测试迭代器将返回undefined。 如果找到匹配的元素,函数将立即返回,不会遍历整个list。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>underscore--find方法</title>
            <script src="../js/underscore.js"></script>
        </head>
        <body>
            <script type="text/javascript">
                //_.find
                var data = [1,2,3,4,5,6];
                var aa=_.find(data,function(num) {
                    return num % 2 == 0;
                });
                console.log("数据类型是"+typeof aa+";返回值是"+aa);  //打印结果是:数据类型是number;返回值是2
            </script>
        </body>
    </html>

    六 _.filter函数

    (1)标准写法:_.filter(list, predicate, [context])

    (2)遍历list中的每个值,返回所有通过predicate真值检测的元素值.

    (3)如果没有值传递给测试迭代器将返回undefined。 如果找到匹配的元素,函数将立即返回,不会遍历整个list。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>underscore--fliter方法</title>
            <script src="../js/underscore.js"></script>
        </head>
        <body>
            <script type="text/javascript">
                //_.filter
                var data2 = [1,2,3,4,5,6];
                var bb=_.filter(data2,function(num) {
                    return num % 2 == 0;
                });
                console.log("数据类型是"+typeof bb+";返回值是"+bb); //打印结果是:数据类型是object;返回值是2,4,6
            </script>
        </body>
    </html>

     

  • jQuery 弹出 插件 layer 实例 总结

    首先向大家推荐layer,在这里也非常感谢贤心的贡献,非常不错的信息框及弹出层解决方案,为一些项目的前端开发提高了很大的效率,希望layer 越办越好!

    下面是API,呵呵,官方抄袭过来的,为了自己看着方便。

    layer API之键值(仅在需要时配置,未配置的会用默认)
    键 : 值描述
    skin : 0层的皮肤编号,值为整数型。目前默认只提供一种皮肤,当你按照样式规则新增皮肤时(详见skin/layer.css),你可配置该参数。
    type : 0,层的类型。0:信息框(默认),1:页面层,2:iframe层,3:加载层,4:tips层。此为重要参数,不同类型层类型的总开关,调用时必须设置。
    shade : [0.5 , ‘#000’ , true]控制遮罩。0.5:遮罩透明度,’#000′:遮罩颜色,true:是否遮罩(否:false)
    shadeClose : false用来控制点击遮罩区域是否关闭层。(是:true)。
    fix : true,层是否固定在可视区域。否:false
    move : [‘.xubox_title’ , true]控制层拖拽。’.xubox_title’:拖拽绑定事件所在元素选择器(默认为标题栏),true:是否允许拖拽(否:false)
    title : [‘信息’ , true]控制标题栏。’信息’:标题栏文字,true:是否显示标题栏(否:false)
    offset : [‘220px’ , ‘50%’]控制层坐标。’220px’:纵坐标,’50%’:横坐标。 需要注意的是,像素必须带px单位,百分比不需要。该参数灵活运用,可助你实现诸多特效。
    area : [‘310px’ , ‘auto’]控制层宽高。’310px’:宽,’auto’:高。 当设置为auto时,意味着采用自适应, 当然,对于宽度,并不推荐您这样做。
    closeBtn : [0 , true]控制层右上角关闭按钮。0:关闭按钮风格(1:风格2),当标题栏不存在时,自动切换为风格2。 true:是否显示关闭按钮(否:false)
    time : 0自动关闭等待秒数,整数值。也许它可以助你做蛮多事,想象一下吧。
    border : [10 , 0.3 , ‘#000’, true]10:边框大小,0.3:边框透明度,’#000′:边框颜色,true:是否显示边框(否:false)。通过它您可以任意配置边框,譬如你觉得边框碍眼,赶紧启用[0,0,”,false]吧
    zIndex : 19891014控制层堆叠顺序(z-index)。整数值,默认是贤心的生日。合理设置它,可以避免与其它插件的层级冲突
    maxWidth : 400最大宽度。整数值。当宽度设为auto时才有用。
    fadeIn : [300 , false]控制层的渐显。300:渐显频率,false:是否开启渐显(默认不开启,true:开启) 从来都觉得这参数形同虚设。
    dialog: {
        btns : 1,
        btn : ['确定', '取消'],
        type : 3,
        msg : '',
        yes : function(index){ },
        no : function(index){ }
    }
    信息框层模式提供的私有参数。使用时,按需配置即可btns : 按钮的个数。提供了0-2的选择

    btn : [按钮一的文本值 , 按钮二的文本值]

    type : 图标类型,提供了0-10的选择,也许有你喜欢的。

    msg : 信息框内容,重要参数

    yes : 按钮一的回调函数

    no : 按钮二的回调函数

    page: {
    	dom: '#xulayer', 
    	html: ''
    }
    页面层模式私有参数。dom:需要弹出的html片段所对应的选择器(class 或 id,推荐用id,确保唯一)。需要注意的是,html优先级高于dom,这意味着,当你一旦配置了html的非空值,将优先采用html中的元素弹出,并且不支持area的自适应模式,你必须配置宽高值。html参数为layer-v1.5.1开始新增。
    iframe: {
     src: 'http://laoji.org'
    }
    iframe层模式私有参数。src:要打开的网址。使用率非常高,尤其是对于喜欢用iframe的同学。
    loading : {type : 0}加载层私有属性。type:loading图标类型(提供了0-3的选择,试试吧,看看有无你喜欢的)。一般配合ajax使用
    tips : {
        msg: '',
        follow: '',
    	guide: 0,
    	style: ['tips自定义样式', '三角形颜色']
    }
    tips小提示层私有属性。msg:提示内容,follow:触发事件对应的选择器。 guide:指引方向(0:上下,1:左右)。[自定义样式示例] style: [‘background-color:#FFF8ED; color:#000; border:1px solid #FF9900’, ‘#FF9900’]]。layer-v1.5.1开始,对tips逐渐有了较为完善的支持,提供了上下和左右模式,可智能识别指引方向。
    success : function(layer){}层弹出成功后的回调函数
    close : function(index){}层右上角关闭按钮的回调函数。
    end : function(){}层被彻底关闭后执行的回调函数。它的存在让close回调成为浮云。
    layer API之内置方法
    方法名描述
    $.layer({})核心接口,参数是一个对象,对象属性参见上述列表。诸如layer.alert()之类的为$.layer()的包装方法。
    layer.v获取版本号。
    layer.ready(callback)layer中的样式文件装载完毕后执行的方法,一般用于页面加载时调用layer,这样可避免样式未加载即调用层导致的错乱。 示例:

    layer.ready(function(){
    	layer.msg('Hello Layer');
    });
    layer.alert()对单按钮信息框的重新封装,layer.alert(alertMsg , alertType, alertTit , alertYes),四个参数,alertMsg:信息内容(文本),alertType:提示图标(整数,0-10的选择),alertTit:标题(文本),alertYes:按钮的回调函数。 如:layer.alert(‘前端攻城师贤心’)
    layer.confirm()对询问框的重新封装,layer.confirm(conMsg? , conYes , conTit , conNo),四个参数,conMsg:信息内容(文本),conYes:按钮一回调,conTit:标题(文本),conNo:按钮二的回调。??????????????????? 如:

    layer.confirm('确定删除?', function(){ 
    layer.msg('删除成功!') 
    });
    layer.msg()对无标题栏信息框层的重新封装,layer.msg(msgText , msgTime , msgType , callback),四个参数,msgText:信息内容(文本),msgTime:自动关闭所需等待秒数(默认2秒),msgType:提示图标(整数,0-10的选择),callback:自动销毁后的回调函数。如:layer.msg(‘嗨,伙计,我是layer’)
    layer.tips()对tips层的重新封装,layer.tips(html , follow , time , maxWidth, guide, style),四个参数,html:信息内容(文本),follow:触发事件对应的选择器,time:自动关闭所需等待秒数,maxWidth:最大宽度,guide: 0(上下模式)或者1(左右模式) style: tips样式(参加api表格一中的style属性)如:

    $('.demo').click(function(){
    	layer.tips('这是小提示',this);
    });
    layer.load()对加载层的重新封装,layer.load(loadTime , loadgif , loadShade),三个参数,loadTime:自动关闭所需等待秒数(0时则不自动关闭),loadgif:加载图标(整数,0-3的选择),loadShade:是否遮罩(true 或 false)。如:layer.load(0);
    layer.getChildFrame(selector)获取子iframe中的DOM。非常实用,父窗口操作iframe中内容时可以大显神威。如:layer.getChildFrame(‘body’).html() //得到iframe的body的全部html元素
    layer.getFrameIndex()获取iframe层的索引。 如在iframe页中关闭自身:

    var i = parent.layer.getFrameIndex();
    parent.layer.close(i);
    layer.close(index)用于手动关闭层。参数为layer的索引值。索引即通过弹出方法返回的值。如:

    var i = $.layer({}); //或者 var i = layer.alert();之类的也可返回索引
    layer.close('i');
    layer.shift(type , rate)layer弹出时内置动画,type:动画类型,供四种中选择,左上:’left-top’,右上:’right-top’,左下:’left-bottom’,右下:’right-bottom’ 。 rate:动画频率,毫秒。 如:

    success : function(){
       layer.shift('right-bottom' , 400);
    }
    layer.autoArea(index)用来处理在层中宽高改变时,重新自适应层宽高。必填参数为层的索引值
    layer.iframeAuto()用于让iframe层自适应。非常实用,详见官网实例演示之iframe子父操作。
    layer.setMove()当拖拽元素改变时,可用此方法重新初始化拖拽。
  • jQuery Mobile 插件 使用实例 总结

    我们这里总结一下jQuery Mobile 插件在使用实际过程中用到的一些方法、函数。

    jQuery Mobile get current page 获取当前page

    var activePage = $.mobile.activePage.attr(“id”);

     

    jQuery Mobile?当一个page页面被显示时的事件:

    $(document).delegate(‘#page-verify’,’pageshow’,function(){
    //当id为page-verify的page被显示时的事件
    });

  • PHP bcsub 不能用 php-bcmath 扩展安装

    今天在迁移一台服务器以后发现有个页面出现空白,无任何报错,后来分析代码发现有个函数bcsub,注释掉以后就可以使用了。

    运行bcsub函数需要 php-bcmath的扩展。

    Php: BCMath

    bc是Binary Calculator的缩写。bc*函数的参数都是操作数加上一个可选的 [int scale],比如string bcadd(string $left_operand, string $right_operand[, int $scale]),如果scale没有提供,就用bcscale的缺省值。这里大数直接用一个由0-9组成的string表示,计算结果返回的也是一个 string。

    bcadd — 将两个高精度数字相加

    bccomp — 比较两个高精度数字,返回-1, 0, 1

    bcdiv — 将两个高精度数字相除

    bcmod — 求高精度数字余数

    bcmul — 将两个高精度数字相乘

    bcpow — 求高精度数字乘方

    bcpowmod — 求高精度数字乘方求模,数论里非常常用

    bcscale — 配置默认小数点位数,相当于就是Linux bc中的”scale=”

    bcsqrt — 求高精度数字平方根

    bcsub — 将两个高精度数字相减

    可以参考手册去查这些函数的应用。

    bcmath的安装:
    yum install php-bcmath
    Reload php-fpm,nginx
    systemctl reload nginx.service
    systemctl reload php-fpm.service
    重新打开页面,恢复正常。
  • Nginx 下 ThinkPHP URL 的 PATHINFO 与 REWRITE 重写 配置方法

    尝试了下 ThinkPHP 框架, 版本为 3.2.3。本文内容为解决 Nginx 下 ThinkPHP URL 模式中所用到的 PATHINFO 与 REWRITE 模式的配置问题。并在 Mac OS X 10.10 下 Nginx 1.8.0 + PHP 5.6.8 下测试通过。理论同样适用于各版本的 Linux 系统中。

    PATHINFO 与 REWRITE 模式在表现上的不同在于浏览器的 URL 地址栏中, 以访问 Home 模块, User 控制器, login 操作为例:

    PATHINFO 下的 URL: http://laoji.org/index.php/Home/User/login
    REWRITE 下的 URL: http://laoji.org/Home/User/login

    Nginx 开启 PATHINFO

    在这之前, 笔者也到搜索引擎上看了几篇关于 Nginx 配置 PATHINFO 的方法, 感觉有点乱, 乱的原因主要是由于 Nginx 没有给予像 Apache 那样一个参数即可开启 PATHINFO 的良好支持, 因此出现了各种 Nginx 下开启 PATHINFO 的解法。

    这里提供的是参阅 Nginx 官方文档并结合实测可用后的 PATHINFO 的方案。去除不必须的注释, Nginx 开启 PATHINFO 的 server 部分配置如下:

    server {
    listen 80;
    server_name localhost;

    location / {
    root /wwwroot/laoji.org; # 你的 TP 框架 index.php 所在目录, 记得用 / 分割路径
    index index.php index.html index.htm;
    }

    # …

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ ^(.+\.php)(.*)$ {
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;

    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME? $document_root$fastcgi_script_name;
    include fastcgi_params;
    }
    }

    这种做法的原理是当请求的访问路径中含有 .php 时, 通过正则表达式构造出 PATHINFO, 并设置到 fastcgi 的参数 PATH_INFO 中。

    代码中匹配 PATH_INFO 的正则表达式来源于 Nginx 官方文档中的写法。参见:http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info

    PATHINFO 模式是 ThinkPHP 默认的 URL 模式, 因此不需要修改 ThinkPHP 的默认配置即可使用http://serverName/index.php/模块/控制器/操作 方式访问。


    URL REWRITE 模式

    REWRITE 模式也称 URL重写, 可用于隐藏 PATHINFO 模式路径中的 index.php, 开启 REWRITE 模式的 Nginx 配置为:

    server {
    listen 80;
    server_name laoji.org;

    location / {
    root /wwwroot/laoji.org;
    index index.php index.html index.htm;
    try_files $uri $uri/ /index.php?s=$uri; # 核心
    }

    # …

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME? $document_root$fastcgi_script_name;
    include fastcgi_params;
    }
    }

    配置完成后修改 ThinkPHP 的 URL 模式为 REWRITE, 编辑配置文件 ThinkPHP/Conf/convention.php 中修改 URL_MODEL 参数值为 2 (REWRITE 模式)即可通过 http://serverName/模块/控制器/操作 方式访问。

  • CentOS配置Nginx官方Yum源 进行安装 图文教程

    CentOS配置Nginx官方Yum源 进行安装 图文教程

    nginx

    这不是前两天子凡搞了个小鸟云的免费云主机,正准备搭建个WEB环境来玩玩,结果直接使用“yum -y install nginx”安装才发现默认yum仓库没有nginx,所以就无法直接安装nginx了,所以今天就和子凡一起来简单的配置一下吧!

    由于yum源中没有我们想要的nginx,那么我们就需要创建一个“/etc/yum.repos.d/nginx.repo”的文件,其实就是新增一个yum源。

    vi /etc/yum.repos.d/nginx.repo

    然后将下面的内容复制进去:

    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=0
    enabled=1

    然后保存“/etc/yum.repos.d/nginx.repo”文件后,我们就使用yum命令查询一下我们的nginx的yum源配置好了没有。

    # yum list |grep nginx
    nginx.x86_64 1:1.10.1-1.el7.ngx nginx
    nginx-debug.x86_64 1:1.8.0-1.el7.ngx nginx
    nginx-debuginfo.x86_64 1:1.10.1-1.el7.ngx nginx
    nginx-module-geoip.x86_64 1:1.10.1-1.el7.ngx nginx
    nginx-module-image-filter.x86_64 1:1.10.1-1.el7.ngx nginx
    nginx-module-njs.x86_64 1:1.10.1.0.0.20160414.1c50334fbea6-1.el7.ngx
    nginx
    nginx-module-perl.x86_64 1:1.10.1-1.el7.ngx nginx
    nginx-module-xslt.x86_64 1:1.10.1-1.el7.ngx nginx
    nginx-nr-agent.noarch 2.0.0-9.el7.ngx nginx
    pcp-pmda-nginx.x86_64 3.10.6-2.el7 base

    如果执行命令是这样的显示效果,那么我们的nginx的yum源就配置成功啦!

    然后要安装我们的nginx就直接执行:

    yum -y install nginx

    如果操作正确到这里nginx环境就已经安装OK了。

    当然你还可以使用命令查一下究竟是否安装完成。

    # rpm -q nginx
    nginx-1.10.1-1.el7.ngx.x86_64

    不解释,已经成功了,并且是nginx官方的最新版本。

  • Discuz! X3 更换域名 迁移服务器 实例

    准备工作 :

    因为域名更换了,因此原域名就不能再进后台了,请申请好新域名,并正确备案,让机房添加白名单,重新解析,重新绑定空间….. 完成一系列工作后,进入DZ程序修改。

    正式工作:

    1、把config/config_global.php??和 config_global_default.php 中的内容相应修改

    $_config['cookie']['cookiedomain'] = '.laoji.org';
    $_config['admincp']['runquery'] = 1;? ? ? ? ? ? ? ? // 是否允许后台运行 SQL 语句 1=是 0=否[安全]

    我们有时在迁移服务器后,使用IP临时访问时可能会遇到admin.php无法登陆的情况,记得修改一下上面的$_config[‘cookie’][‘cookiedomain’],否则cookie不对,造成无法登陆。点击之后变成了刷新页面。

    2、请直接使用 http://新域名/admin.php 登录后台。
    3、需要修改哪些东西呢?

    1.后台==>全局==>站点信息==>网站url

    2.后台==>全局==>域名设置==>应用域名==>论坛和根域名设置手机版访问设置:— 手机发帖来源自定义:

    3.后台==>界面==>导航==>链接里面使用了绝对地址需要修改为新域名

    4.后台==>运营==>关联连接,没有设置就不用修改,在这里主要涉及优化??(站点宣传广告、友情链接)

    5.后台==>云平台==>同步站点信息? ?后台—工具—去平台诊断工具 (可能要手动设置IP)

    6.后台==>站长==>ucernter设置==>ucenter访问地址7.ucenter==>应用管理==>应用的主url

    如果是*Unix服务器,记得修改文件权限。

    BBS导航—顶部、底部??(版规网址要更新),论坛格子广告,贴间广告,列表广告全部要更新。**************
    修改遇到的问题解答:

    1.如果您已经修改了域名解析请直接使用http://新域名/admin.php登录之后,进行上述修改
    2.后台登陆不了,被自动退出请把config/config_global.php中的$_config[‘admincp’][‘checkip’] = 1;修改为$_config[‘admincp’][‘checkip’] = 0;

    ———————–
    完成以上工作后,您已经可以正常访问新域名了,但是原来已经发贴的内容网址没有变化,要执行下面的步骤才会变新网址。

  • WeTest 腾讯质量开放平台 WeTest服务器压力测试-简单模式介绍

    WeTest腾讯质量开放平台,国产DDCC免费利器。不需要验证域名所有权就可以做HTTP直接压力测试。照这个套路可以轻松打死一般小站。

    官方直达链接:http://wetest.qq.com/gaps

    逢年过节如果坐高铁回家的话一定要上12306来刷票,然而可能已经代表中国处理最高并发用户复杂请求的12306也经常会承受不住巨大的请求量。

    为了买票,我们也是忍了,如果不是非用不可的网站,恐怕经常给出这样的提示之后用户就直接流失了。准确掌握服务器的可承受能力是非常重要的,服务器在上线之前一定要测试其负载能力,以免出现用户因服务器无法访问而流失的情况。

    WeTest压测最近推出了简单模式,主要是针对Web网站、APP服务器提供压力源、URL直压以及测试结果分析。
    WeTest简单模式主要有以下几个特点:
    简单。人类懒的特性驱动着科技的进步,使用简单模式的时候用户不用写代码,只需简单的点点就可以啦。
    易用。WeTest平台提供压力机,可以无上限从云端产生压力。
    可视化。通过在服务器部署监控进程可以生成多种性能报表,指标一目了然,方便分析和诊断问题。
    业务场景模拟。对于复杂的场景可以通过编程来实现,真实模拟现网业务。

    我们以百度首页为例,看看如何在一分钟内发起压力的。
    1.首先点击压测产品首页中的快捷入口:HTTP直压。

    2.模式选择简单模式,名称和描述可以自己填写,起始人数这里选择5人,每隔30秒增加5人,直到加到10人上限。

    3.新建一个客户端请求,方法选择GET,URL就直接填写“http://www.baidu.com ”,URL变量和Header变量这里可以不填了。

    注:填写Header信息或修改参数化变量可以满足更高要求的测试场景,具体可以查看更一步的帮助,在本篇中不作展开

    4.编辑一下测试模型,增加一个场景名,压测场景选择百度的URL,由于只有一个压测场景,所以把所有100%的压力都放在该场景上。

    由于我们测的是百度首页,不是我们自己的服务器,无法去服务器上部署性能观测工具监测CPU,内存等性能情况,这里就可以不用填。

    5.保存设置。

    您也可以选择‘立即执行’这个测试,测试会马上进入排队系统,如果压力源系统内有空闲资源将马上为您执行测试

    6.保存之后会跳转到测试用例列表,这里我们点击开始即可进行测试。

WeChat
↑