json_decode

今天在操作json_decode之后的数组的时候发现结构是这样的

带有stdClass上网直接搜索stdClass说是什么zend的保留函数云云

没有给出实际的操作方法

 

然后查了一下手册发现json_decode的第二个参数设置为true时返回array而并非object

mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

所以加上第二个参数就ok了

 

jQuery 总结

========================== 

为了简化js的开发,一些js库诞生了 

流行的有:jQuery, Moo Tools, Prototype, Dojo,YUI,EXT_JS,DWR 

 

========================== 

jQuery  — javascript query   

轻量级js库,兼容css3,兼容各种浏览器 

快速、简洁 

方便处理HTML documents、events、实现动画效果, 

方便的为网站提供ajax交互 

文档说明全,很多成熟插件可选择 

能够使html保持代码和html内容分离 

 

========================== 

什么是jquery对象 

就是通过jquery包装dom对象后产生的对象 

jquery对象是jquery独有的 

可以使用方法$("#test").html(); 

意思是:获取ID为test的元素内的html代码 

等同于用DOM实现: 

document。getelementById("test")[removed]; 

通过id直接输出 

alert($("#name").val()); 

注意!! DOM和JQUERY不能互相使用 

约定 jquery对象前面加上$ 

var $var = jquery对象 

var variable = DOM对象 

 

========================== 

DOM对象转成jquery对象 

吧DOM对象用$()包装起来 

jquery对象=$(dom对象) 

 

jquery对象转换成dom对象 

1)[index] 

jquery对象是一个数组对象 

var use = $use[0]; 

2).get(index) 

jquery本身提供的方法 

var use = $use.get(0); 

 

========================== 

jquery选择器 jquery的根基 

对事件处理,遍历dom和ajax操作都依赖选择器 

 

优点 

简介的写法 

$("#id") 等价document.getElementByid("id"); 

$("tagName")等价 document.getElementByTagName("tagName"); 

 

完善的时间处理机制 

 

基本选择器 

1.#id  

用法:$("#myDiv");  返回值 单个元素组成的集合 

说明:这个就是直接选择html中的id="myDiv"  匹配的第一个 

2.Element   

用法:$("div")   返回值 集合元素 

说明:element就是html已经定义的标签元素.如div,input,等 

3.class   

用法:$(".myClass") 返回值 集合元素 

说明:这个标签直接选择html代码中class="myClass"的元素或元素族 

4. * 

用法:$("*") 返回值 集合元素 

说明:匹配所有元素,多用于结合上下文来搜索 

5.selector1,selector2, selectorN 

用法:$("div.span.p.myClass") 返回值 几何元素 

说明: 将每一个选择器匹配到的元素合并后一起返回,可以指定任意多个选择器 

并将匹配到的元素合并到一个结果内,p.myClass表示匹配p class = "myClass" 

 

层次选择器 

通过DOM元素之间的层次关系,如后代,子,相邻,兄弟 

1.ancestor descendant 

用法:$("form input"); 返回值 集合元素 

说明 在给定的祖先元素下匹配所有后代元素 

2.parent > child 

用法:$("form>input") 返回值 集合元素 

说明给定的父元素下匹配所有的子元素 

!!注意 子元素和后代元素 

3.prev + next 

用法: $("label+input") 返回值 集合元素 

说明: 匹配所有紧接在prev元素后的next元素 

4.prev~siblings 

用法: $("form ~ input") 返回值 集合元素 

说明 匹配prev元素之后的所有 siblings同辈元素, 匹配的是和prev同辈的元素,后辈元素不被匹配 

siblings()方法匹配所有同辈 包括之前的 

 

 

 

过滤选择器 

通过特定的过滤规则筛选出所需的dom元素.以":"开头 

按不同的过滤规则.过滤选择器分为 

基本过滤,内容过滤,可见性过滤 

属性过滤,子元素过滤和表单对象属性过滤选择器 

 

基本过滤选择器 

1. :first 

用法 $("tr:first"); 返回值 单个元素组成的集合 

说明:匹配找到的第一个元素 

2. :last 

用法 $("tr:last"); 返回值 集合元素 

说明:匹配找到的最后一个元素,与:first相对应 

3. :not(selector) 

用法 $("input:not(:checked)"); 返回值 集合元素 

说明:去除所有与给定选择器匹配的元素,类似于“非” 

指没有被选中的input(当input的type为checkbox) 

4. :even 

用法 $("tr:even") 返回值  集合元素 

说明: 匹配所有索引值为偶数的元素.从0开始计数 

5.dd 

用法 $("tr:odd") 返回值  集合元素 

说明: 匹配所有索引值为奇数的元素.与even相应,从0开始计数 

6. :eq(index) 

用法 $("tr:eq(0)") 返回值  集合元素 

说明: 匹配一个给定索引值的元素。eq(0)就是获取第一个tr元素, 

注意括号内为索引值 不是元素排列数 

7. :gt(index) 

用法 $("tr:gt(0)") 返回值  集合元素 

说明: 匹配所有大于给定索引值得元素。 

8. :lt(index) 

用法 $("tr:lt(2)") 返回值  集合元素 

说明: 匹配所有小于给定索引值得元素。 

9. :header(固定写法) 

用法 $(":header").css("background","red") 返回值 集合元素 

说明: 匹配如h1,h2,h3之类的标题元素 

10. :animated(固定写法) 返回值  集合元素 

说明:匹配所有正在执行动画效果的元素 

内容过滤选择器 

1. :contains(text) 

用法:$("div:contains('John')") 返回值 集合元素 

说明 匹配包含给定文本的元素,查找被标签围起来的文本内容是否符合指定的内容 

2. :empty 

用法  $("td:empty") 返回值 集合元素 

说明:匹配所有不包含子元素或者文本的空元素 

3. :has(selector) 

用法  $("div:has(p)").addClass("test") 返回值 集合元素 

说明:匹配含有选择器所匹配的元素的元素,给包含P元素的div加上class=‘test’ 

4. :parent 

用法  $("td:parent") 返回值 集合元素 

说明:匹配含有子元素或者文本的元素 与empty相反 

可见度过滤选择器 

根据元素的可见和不可见状态来选择相应的元素 

1. :hidden    jquery的show()显示 

用法  $("tr:hidden") 返回值 集合元素 

说明:匹配所有的不可见元素  css中的display:none和input type="hidden" 

2. :visible 

用法  $("tr:visible") 返回值 集合元素 

说明:匹配所有的可见元素 

属性过滤选择器  【注意 是方括号不是冒号":"】 

通过元素的属性来获取相应的元素 

1.[attribute] 

用法:$("div[id]") 返回值 几何元素 

说明: 匹配包含给定属性的元素,   选取了带id属性的div标签 

2.[attribute=value] 

用法:$("input[name='newsletter']").attr("checked",true) 返回值 几何元素 

说明: 匹配包含给定属性是某个特定值的元素,   

选取了所有name属性是newsletter的input元素 

3.[attribute!=value] 

用法:$("input[nam!e='newsletter']").attr("checked",true) 返回值 几何元素 

说明: 匹配不含油给定属性,或者属性不等于某个特定值的元素, 

等价于not(attr=value), 

选取了所有name属性是newsletter的input元素 

4.[attribute^=value] 

用法:$("input[name^='news']") 返回值 几何元素 

说明: 匹配包含给定属性是以某些值开始的元素  

5.[attribute$=value] 

用法:$("input[name$='letter']") 返回值 几何元素 

说明: 匹配包含给定属性是以某些值结尾的元素 

6.[attribute*=value] 

用法:$("input[name*='man']") 返回值 几何元素 

说明: 匹配包含给定属性是以包含某些值的元素 

7.[attributeFilter1][attributeFilter2][attributeFilterN] 

用法:$("input[id][name$='man']") 返回值 几何元素 

说明:符合属性选择器,需要同时满足多个条件时使用 

子元素过滤选择器 

1 :nth-child(index/even/odd/equation) 

用法: $("ul li:nth-child(2)") 返回值 集合元素 

说明 匹配其父元素下的第几个子奇偶元素    索引从1开始 

2. :first-child 

用法: $("ul li:first-child(2)") 返回值 集合元素 

说明 为每个父元素匹配第一个子元素, 

3. :last-child 

用法: $("ul li:last-child(2)") 返回值 集合元素 

说明 为每个父元素匹配最后一个子元素, 

4.nly-child 

用法: $("ul li:only-child(2)") 返回值 集合元素 

说明 如果某个元素师父元素中唯一的子元素,那将会匹配 

表单对象属性过滤选择器 

对选择的表单元素进行过滤 

1. :enabled 

用法: $("input:enabled") 返回值 集合元素 

说明 匹配所有可用元素。 查找所有input中不带disable的input 

2. :disabled 

用法: $("input:disabled") 返回值 集合元素 

说明 匹配所有不可用元素。 查找所有input中带disable的input 

3. :checked 

用法: $("input:checked") 返回值 集合元素 

说明 匹配所有选中的被选中的元素(复选框,单选框,不包select中的option) 

4. :selected 

用法: $("input:selected") 返回值 集合元素 

说明 匹配所有选中的option元素 

表单选择器 

1. :input $(":input") 

2. :text $(":text") 

3. :password $(":password") 

4. :radio $(":radio") 

5: :checkbox $(":checkbox") 

6. :submit $(":submit") 

7. :image $(":image") 

8. :reset $(":reset") 

9. :button $(":button") 

10.:file $(":file") 

11.:hidden $("input:hidden") 

 

========================== 

遍历集合 

each(function(index,domEle)) 

参数 

index: 每次索引,从0开始 

domEle: 遍历集合的当前对象,是一个dom对象 

 

this对象的使用,当前遍历的对象 

 

jquery中的全局函数 

$.each(object,function(index,domEle));用来遍历数组及任何对象 

参数 

index: 对象成员或数组索引 

domEle: 对应变量和内容 

 

========================== 

jquery中的dom操作 

dom操作的分类 

dom core 

html dom 

使用js和dom为html编写脚本是。用的很多属性 

css-dom 

js中,主要用于获取和设置上腾娱乐对象的各种书新娘歌 

 

内部插入节点 

append(content) 

向每个匹配元素的内部的结尾处追加内容 

appendTo(content) 

将每个匹配的元素追加到指定的元素中的内部结尾处 

prepend(content) 

向每个匹配元素的内部的开始处追加内容 

prependTo(content) 

将每个匹配的元素追加到指定的元素中的内部开始处 

 

外部插入节点 

after(content) 

在每个匹配的元素之后插入内容 

before(content) 

在每个匹配的元素之前插入内容 

insertAfter(content) 

把所有匹配的元素插入到另一个、指定的元素元素集合的后面 

insertBefore(content) 

把所有匹配的元素插入到另一个、指定的元素元素集合的前面 

 

不但能将新创建的dom元素插入到文档中,也能对原有的dom元素进行移动 

 

查找节点 

查找属性节点 

jquery选择器 

查到后可调用jquery的attr()方法来获取各种属性值\ 

 

创建节点 

使用jquery的工厂函数$()    如 $(html) 

将传入的html标记字符串创建一个dom对象,并包装成一个jquery对ian 

注意 

动态创建的新元素节点不会被自动添加到文档 

创建单个元素时,注意闭合标签和使用标准的xhtml格式 

 

删除节点 

remove() 

从dom中删除所有匹配的元素,通过jquery表达式来筛选元素 

empty() 

清空节点- 清空元素中所有的后代节点(不包含属性节点) 

 

替换节点 

replaceWith() 

将所有匹配的元素替换为制定的html或dom元素 

replaceAll() 

颠倒了的replaceWith() 

注意:替换之前,元素上绑定的事件会随着替换一起消失 

 

复制节点 

clone() 

复制的新节点不具有任何行为 

clone(ture) 

连同事件一起复制 

 

属性操作 

attr() 

html() 

text() 

val() 

height() 

width() 

css() 

removeAttr() 

jquery按元素可见不可见状态来选择

根据元素的可见和不可见状态来选择相应的元素 

1. :hidden    jquery的show()显示 

用法  $("tr:hidden") 返回值 集合元素 

说明:匹配所有的不可见元素  css中的display:none和input type="hidden" 

2. :visible 

用法  $("tr:visible") 返回值 集合元素 

说明:匹配所有的可见元素 

     属性过滤选择器  【注意 是方括号不是冒号":"】 

通过元素的属性来获取相应的元素 

js中apply方法的使用

1、对象的继承,一般的做法是复制:Object.extend

 Object.extend = function(destination, source) { 
    for (property in source) { 
        destination[property] = source[property]; 
    } 
    return destination; 
}

除此之外,还有种方法,就是:Function.apply(当然使用Function.call也是可以的)

Function.apply(obj,args)方法能接收两个参数

    args:这个是数组,它将作为参数传给Function(args–>arguments)

 

<script> 
function Person(name,age){   //定义一个类,人类  
    this.name=name;     //名字  
    this.age=age;       //年龄 
    this.sayhello=function(){alert("hello")};

function Print(){            //显示类的属性 
    this.funcName="Print"; 
    this.show=function(){      
        var msg=[];
        for(var key in this){ 
            if(typeof(this[key])!="function"){
                msg.push([key,":",this[key]].join(""));
            }
        } 
        alert(msg.join(" "));
    };

function Student(name,age,grade,school){    //学生类 
    Print.apply(this,arguments);
    this.grade=grade;                //年级 
    this.school=school;                 //学校 

var p1=new Person("jake",10);
p1.sayhello();
var s1=new Student("tom",13,6,"清华小学");
s1.show();
s1.sayhello();
alert(s1.funcName);
</script>

学生类本来不具备任何方法,但是在Person.apply(this,arguments)后,

在Print.apply(this,arguments)后就自动得到了show()方法

2、利用Apply的参数数组化来提高

我们先从Math.max()函数说起,Math.max后面可以接任意个参数,最后返回所有参数中的最大值。

但是在很多情况下,我们需要找出数组中最大的元素。
var arr=[5,7,9,1]
alert(Math.max(arr))    // 这样却是不行的。一定要这样写

这样写麻烦而且低效。如果用 apply呢,看代码:
function getMax2(arr){
    return Math.max.apply(null,arr);
}
两段代码达到了同样的目的,但是getMax2却优雅,高效,简洁得多。

再比如数组的push方法。
var arr1=[1,3,4];
var arr2=[3,4,5];
如果我们要把 arr2展开,然后一个一个追加到arr1中去,最后让arr1=[1,3,4,3,4,5]
arr1.push(arr2)显然是不行的。 因为这样做会得到[1,3,4,[3,4,5]]

自从有了Apply,事情就变得如此简单
Array.prototype.push.apply(arr1,arr2)

 

<embed height=”0″ id=”xunlei_com_thunder_helper_plugin_d462f475-c18e-46be-bd10-327458d045bd” type=”application/thunder_download_plugin” width=”0″></embed>

数位补全

    总是忘掉这个函数然后每次都要查,记录一下

定义和用法

str_pad() 函数把字符串填充为指定的长度。

语法

str_pad(string,length,pad_string,pad_type)
参数 描述
string 必需。规定要填充的字符串。
length 必需。规定新字符串的长度。如果该值小于原始字符串的长度,则不进行任何操作。
pad_string 可选。规定供填充使用的字符串。默认是空白。
pad_type

可选。规定填充字符串的那边。

可能的值:

  • STR_PAD_BOTH – 填充到字符串的两头。如果不是偶数,则右侧获得额外的填充。
  • STR_PAD_LEFT – 填充到字符串的左侧。
  • STR_PAD_RIGHT – 填充到字符串的右侧。这是默认的。

例子

例子 1

<?php
$str = "Hello World";
echo str_pad($str,20,".");
?>

输出:

Hello World.........

例子 2

<?php
$str = "Hello World";
echo str_pad($str,20,".",STR_PAD_LEFT);
?>

输出:

.........Hello World

例子 3

<?php
$str = "Hello World";
echo str_pad($str,20,".:",STR_PAD_BOTH);
?>

输出:

.:.:Hello World.:.:.

Linux中的EAGAIN含义

http://blog.163.com/niuxiangshan@126/blog/static/1705965952010862259798/

在Linux环境下开发经常会碰到很多错误(设置errno),其中EAGAIN是其中比较常见的一个错误(比如用在非阻塞操作中)。

    从字面上来看,是提示再试一次。这个错误经常出现在当应用程序进行一些非阻塞(non-blocking)操作(对文件或socket)的时候。例如,以 O_NONBLOCK的标志打开文件/socket/FIFO,如果你连续做read操作而没有数据可读。此时程序不会阻塞起来等待数据准备就绪返回,read函数会返回一个错误EAGAIN,提示你的应用程序现在没有数据可读请稍后再试。

    又例如,当一个系统调用(比如fork)因为没有足够的资源(比如虚拟内存)而执行失败,返回EAGAIN提示其再调用一次(也许下次就能成功)。

Linux – 非阻塞socket编程处理EAGAIN错误

 在linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno代码为11(EAGAIN),这是什么意思?

 这表明你在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket的同步,不用管它,下次循环接着recv就可以。对非阻塞socket而言,EAGAIN不是一种错误。在VxWorks和Windows上,EAGAIN的名字叫做EWOULDBLOCK。

 另外,如果出现EINTR即errno为4,错误描述Interrupted system call,操作也应该继续。

 最后,如果recv的返回值为0,那表明连接已经断开,我们的接收操作也应该结束。

  iReadSizeOnce=read(iOpenCom,RxBuf+iReadSize,1024);

    if (iReadSizeOnce != ZERO)

    {

        if (iReadSizeOnce != EAGAIN)

        {

            continue;

        }

        else

        {

            //stCComApiLog.LogError("读串口操作错误");

            return(FUN_ERROR);

        }

    }

EPOLL 边缘触发学习

在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。

相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。并且,在linux/posix_types.h头文件有这样的声明:

#define __FD_SETSIZE    1024

表示select最多同时监听1024个fd,当然,可以通过修改头文件再重编译内核来扩大这个数目,但这似乎并不治本。



epoll的接口非常简单,一共就三个函数:

1. int epoll_create(int size);

创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大。这个参数不同于select()中的第一个参数,给出最大监听的fd+1的值。需要注意的是,当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。





2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll的事件注册函数,它不同与select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。第一个参数是epoll_create()的返回值,第二个参数表示动作,用三个宏来表示:

EPOLL_CTL_ADD:注册新的fd到epfd中;

EPOLL_CTL_MOD:修改已经注册的fd的监听事件;

EPOLL_CTL_DEL:从epfd中删除一个fd;

第三个参数是需要监听的fd,第四个参数是告诉内核需要监听什么事,struct epoll_event结构如下:

struct epoll_event {

  __uint32_t events;  /* Epoll events */

  epoll_data_t data;  /* User data variable */

};



events可以是以下几个宏的集合:

EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);

EPOLLOUT:表示对应的文件描述符可以写;

EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);

EPOLLERR:表示对应的文件描述符发生错误;

EPOLLHUP:表示对应的文件描述符被挂断;

EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。

EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里





3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

等待事件的产生,类似于select()调用。参数events用来从内核得到事件的集合,maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size,参数timeout是超时时间(毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞)。该函数返回需要处理的事件数目,如返回0表示已超时。



——————————————————————————————–



从man手册中,得到ET和LT的具体描述如下



EPOLL事件有两种模型:

Edge Triggered (ET)

Level Triggered (LT)



假如有这样一个例子:

1. 我们已经把一个用来从管道中读取数据的文件句柄(RFD)添加到epoll描述符

2. 这个时候从管道的另一端被写入了2KB的数据

3. 调用epoll_wait(2),并且它会返回RFD,说明它已经准备好读取操作

4. 然后我们读取了1KB的数据

5. 调用epoll_wait(2)……



Edge Triggered 工作模式:

如果我们在第1步将RFD添加到epoll描述符的时候使用了EPOLLET标志,那么在第5步调用epoll_wait(2)之后将有可能会挂起,因为剩余的数据还存在于文件的输入缓冲区内,而且数据发出端还在等待一个针对已经发出数据的反馈信息。只有在监视的文件句柄上发生了某个事件的时候 ET 工作模式才会汇报事件。因此在第5步的时候,调用者可能会放弃等待仍在存在于文件输入缓冲区内的剩余数据。在上面的例子中,会有一个事件产生在RFD句柄上,因为在第2步执行了一个写操作,然后,事件将会在第3步被销毁。因为第4步的读取操作没有读空文件输入缓冲区内的数据,因此我们在第5步调用 epoll_wait(2)完成后,是否挂起是不确定的。epoll工作在ET模式的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。最好以下面的方式调用ET模式的epoll接口,在后面会介绍避免可能的缺陷。

   i    基于非阻塞文件句柄

   ii   只有当read(2)或者write(2)返回EAGAIN时才需要挂起,等待。但这并不是说每次read()时都需要循环读,直到读到产生一个EAGAIN才认为此次事件处理完成,当read()返回的读到的数据长度小于请求的数据长度时,就可以确定此时缓冲中已没有数据了,也就可以认为此事读事件已处理完成。



Level Triggered 工作模式

相反的,以LT方式调用epoll接口的时候,它就相当于一个速度比较快的poll(2),并且无论后面的数据是否被使用,因此他们具有同样的职能。因为即使使用ET模式的epoll,在收到多个chunk的数据的时候仍然会产生多个事件。调用者可以设定EPOLLONESHOT标志,在 epoll_wait(2)收到事件后epoll会与事件关联的文件句柄从epoll描述符中禁止掉。因此当EPOLLONESHOT设定后,使用带有 EPOLL_CTL_MOD标志的epoll_ctl(2)处理文件句柄就成为调用者必须作的事情。

tornado日志

define,options头文件

from tornado.options import define, options
tornado的define(在命令行中没有该定义的参数时时,使用这里的默认值)

define("port", default=8889, help="Run server on a specific port", type=int)

 

解析命令行参数

tornado.options.parse_command_line()

 

写log

import logging
logging.debug("debug .... ")

 

命令行执行和log格式

python myserver.py -port=8888 -log_file_prefix=var/log/test_log@8888.log
python myserver.py -port=8889 -log_file_prefix=var/log/test_log@8889.log
-------------
# -*- coding: utf-8 -*-
"""启动web server"""
import tornado.ioloop
from application import application
from tornado.options import define, options
import logging
define("port", 8889, help="port", type=int)
if __name__ == "__main__":
    options.parse_command_line()
    logging.debug("debug ...")
    options.parse_command_line()
    application.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()