每日总结:jquery的ajax以及阻止默认事件

今天该bug,遇到一个情况,有一个修改按钮,按钮是有href属性的,在点按钮之前需要向后端请求一下,后端会返回一个标识,然后根据这个标识判断是否要跳转。

刚开始是想在回调里判断标识,如果失败阻止默认事件,并做接下来的处理,但是一直行不通。后来改成点击的时候就阻止,成功了,代码如下:

$(".edit").on("click", function(event){
          event.preventDefault();
          var url = createLink('order', 'checkSaleBeforeEdit', 'id=' + v.orderID);
          var _this = $(this);
          var href = _this.attr('href');
          $.ajax({
            'url':url,
            'type':'post',
            'dataType':'json',
            success:function(data){
              if(data.result == 'fail'){
                alert(v.cantEdit);
                history.go(0);
              }else{
                location.href = href;
              }
            }
          });
      });
    }

过程中还遇到一个问题,本以为回调函数里的作用域跟on函数的作用域不一样,想着变量通过参数传入,后来查资料发现不用,可以直接传入。

每日总结:正则替换,PHP://

1. 正则
<?php
$a = "<a href='javascript:void(0)'>XS1000010011702130002</a>";

$o = "hello";

echo preg_replace_callback("/\<a.*?\>(.*)\<\/a\>/", function($matches){return str_replace($matches[1],$o,$matches[0]);}, $a);

上面这段代码,是想把a标签的内容换成hello,preg_replace_callback(),第二个参数是个回调函数,这里采用匿名(闭包)函数来代替,否则就传入函数名即可。

回调函数的参数是匹配到结果数组,比如这里var_dump($matches),结果为:

  array(2) {
  [0]=>
  string(129) “<a href=’javascript:void(0)’ data-openwin=’true’ data-winid=” data-url=’/scm/order-detail-11932.html’>XS1000010011702130002</a>”
  [1]=>
  string(21) “XS1000010011702130002”
  }

运行代码发现结果不是预想的那样,报错$o不存在,原来忽视了最基本的作用域问题,于是回调函数里加上global $o,再运行ok。

其实在闭包函数里,还可以用use关键字来使用上文的变量。比如这里可以这么写:

<?php
function($matches) use($o){
   //...
}

两种写法都可以。

2. 封装协议

php中有很多封装协议用于url,比如http://,ftp://等等。其中有一个php://,文档中的说明:

说明:PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。

php://output是将数据写入缓冲区,比如:

<?php
$fp = fopen("php://output","r");
fwirte($fp, "helloworld");
// 运行输出“”helloworld“”

php://input 是个可以访问请求的原始数据的只读流,比如post请求的数据:

<?php
// 假设post的数据 {"name":"laokiea"}

 var_dump(file_get_contents("php://input"));\

// result : string(12) "name=laokiea"

具体有篇文章http://www.kuitao8.com/20140727/2867.shtml

 

每日总结:类型约束,自定义错误机制,php变量比较中的一些坑

PHP是一门弱类型语言,定义的变量随着上下文的改变类型可能变来变去,这有利有弊。

从PHP5.0开始,可以强制约束变量的类型,比如对象,数组,整形等等。具体参考手册。比如:

<?php
class A{}
funtion test(A $a)
{
// 约束参数$a必须是A类的对象
//也可以改成array $a,必须是数组
//也可以改成stdClass $a,必须是对象(stdClass只是zend的一个保留类,并不是所有类的基类)
//也可以改成 callable $a,必须是回调类型
}

如果传入的参数跟约束的类型不一样,会出现一个致命的错误。如果不希望这种错误影响到代码的继续运行,可能就需要自定义错误处理函数了。

set_error_handler是php允许用户自己处理错误提示的函数。具体参考手册。

<?php

/*
自定义函数样式 :handler  ( int $errno  , string $errstr  [, string $errfile  [, int $errline  [, array $errcontext  ]]] )
第一个参数 errno,包含了错误的级别,是一个 integer。  
第二个参数 errstr,包含了错误的信息,是一个 string。
第三个参数是可选的,errfile, 包含了发生错误的文件名,是一个 string。
第四个参数是一个可选项, errline, 包含了错误发生的行号,是一个 integer。
第五个可选参数, errcontext, 是一个指向错误发生时活动符号表的 array。 也就是说,errcontext 会包含错误触发处作用域内所有变量的数组。 用户的错误处理程序不应该修改错误上下文(context)。
*/

function myHandler($no,$str,$file,$line.$context){
    if($no == E__ERROR)
    {
        //....
    }
}

set_error_handler("myHandler", null);
// 也可以用对象传入,set_error_handler(array($this, "myHandler"), null);
// 第二个参数类似error_reporting()的功能,设置哪些错误发生时,会触发自定义函数

 

今天解bug时,遇到这么一个判断表达式,$a == 0,$a是个字符串,刚开始没多想以为0等同false,只要$a不为空值,这个等式就不成立,但是var_dump一下发现竟然是true,很纳闷,后来查了一下,恍然大悟:PHP是弱类型,在比较的时候会根据语意自动转换变量的类型,比如0 == “hello”,会先把”hello”转成int类型即为0,所以这里是true。php中的严格应该用恒等于===去作比较,保证值和类型都一样。

每日总结:php位移运算

<< >>是php里的两个位移运算符。比如2<<3,11>>2,其中的计算原理是啥呢?

已3<<2为例,<<表示左移,即3所有的位往左移动2位,首先把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,所有位左移2,前面的位挤掉,后面空出来的补0,那结果就是

0000 0000 0000 0000 0000 0000 0000 1100结果是12,数学原理就是3*2的2次方即:3<<2 == 3*pow(2,2);

11>>2同理,11>>2 == floor(11/pow(2,2));只不过需要向下取整,即除不足为0

<?php

// TIP
$a = "he"; 
$a{1} == $a[1] == 'h';
// {}跟[]的作用一样,表示偏移

 

日期的加减

PHP怎么给日期做加减法?

总结了两种做法:

  1. strtotime()

    <?php
    date("Y-m-d", strtotime("2017-02-09 +1 day"));
    // 输出2017-02-10 表示加一天
    date("Y-m-d H:i:s", strtotime("2017-02-09 23:09:20 +1 minute"));、
    // 输出2017-02-09 23:09:21
    
    // 加号表示增,减号表示减

     

  2. dateTime对象处理
    <?php
    $date = new DateTime("2017-02-09"); // 实例化,参数是一个时间字符串
    $date->add(new DateInterval("P1D"));
    echo $date->format("Y-m-d");
    // 输出2017-02-10
    // DateInterval也是一个内置的类,用于调整时间,说一下构造函数的参数
    // 如果是年月日的加减,参数字串以字母P开头,表示period,如果带上了具体的时间。参数就要带上字母T。
    // 比如:P1Y10M1D表示增加1年10个月1天;PT10H20M10S表示不增加年月日只增加10小时20分钟10秒
    // 另外日期减是sub()函数,两个日期相减是diff()函数