├── FastDFS笔记一览.md ├── Java所有集合的总结.md ├── Java笔记一览.md ├── Java集合LinkedTransferQueue注释翻译.md ├── Mysql_InnoDB笔记一览.md ├── Mysql笔记一览.md ├── PHP,Java和Python的字符串匹配算法(模式匹配).md ├── README.md ├── Redis内部数据结构.md ├── Redis笔记一览.md ├── images ├── FastDFS笔记一览.jpg ├── Java笔记一览.jpg ├── Mysql_InnoDB笔记一览.jpg ├── Mysql笔记一览.jpg ├── PHP_核心原理.png ├── Redis内部数据结构.jpg ├── Redis笔记一览.jpg ├── java数据结构总结.jpg ├── readme.md └── 算法和数据结构笔记一览.jpg ├── linux_sort命令.md ├── linux_查看编码和转码.md ├── markdown基本语法.png ├── markdown语法.md ├── php中的trait.md ├── php利用位运算做权限.md ├── php命名空间.md ├── php对象的赋值&clone&引用&比较.md ├── php扩展_xhprof.md ├── php排序函数.md ├── php核心原理笔记一览.md ├── php的session.md ├── php的自动加载.md ├── php的配置.md ├── php魔术方法.md ├── 如何技术选型.md ├── 微服务优缺点.md ├── 正则表达式.md └── 算法和数据结构笔记一览.md /FastDFS笔记一览.md: -------------------------------------------------------------------------------- 1 | ![FastDFS笔记一览](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/FastDFS%E7%AC%94%E8%AE%B0%E4%B8%80%E8%A7%88.jpg "FastDFS笔记一览") 2 | -------------------------------------------------------------------------------- /Java所有集合的总结.md: -------------------------------------------------------------------------------- 1 | Java所有集合的总结。 2 | - 总结了值重复/顺序/阻塞/同步性/时间复杂度等方面。 3 | - 其中迭代器一致性/内部实现(算法)/功能这3列还未完成。LinkedTransferQueue/Disruptor这两个未完成。 4 | 5 | ![Java所有集合的总结](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/java%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E6%80%BB%E7%BB%93.jpg "Java所有集合的总结") 6 | -------------------------------------------------------------------------------- /Java笔记一览.md: -------------------------------------------------------------------------------- 1 | ![Java笔记一览](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/Java%E7%AC%94%E8%AE%B0%E4%B8%80%E8%A7%88.jpg "Java笔记一览") 2 | -------------------------------------------------------------------------------- /Java集合LinkedTransferQueue注释翻译.md: -------------------------------------------------------------------------------- 1 | 翻译LinkedTransferQueue源码中的Overview of Dual Queues with Slack这段注释。意译,可能有误。 2 | 3 | 《介绍松弛双队列》 4 | 5 | 双队列(Dual Queues),由Scherer和Scott设计的。其中节点可以表示数据(DATA)或请求(REQUEST)。当一个线程试图入列1个数据(DATA)节点时,如果遇到一个请求节点(REQUEST),它俩会进行匹配(match)并且被删除。反过来,对于入列请求(REQUEST)也一样。阻塞双队列(Blocking Dual Queues)让未匹配到节点的入列线程排队等待(阻塞),直到其他线程提供可匹配的节点为止。双同步队列(Dual Synchronous Queues)也会让未匹配到节点的线程阻塞。双传输队列(Dual Transfer Queues)支持所有这些模式。 6 | 7 | 有一种FIFO双队列(FIFO dual queue),实现了Michael & Scott(M&S)的lock-free队列算法。它维护两个指针属性head和tail。head,指向一个匹配的(matched)节点,这个节点又指向第一个实际的未匹配的(unmatched)队列节点,如果队列是空的它就是null。tail指向队列的最后一个节点,如果队列是空的,它就是null。比如下面这个四个节点的队列: 8 | 9 | head tail 10 | | | 11 | v v 12 | M -> U -> U -> U -> U 13 | 14 | M&S队列算法通过CAS操作维护head和tail指针时,容易实现可伸缩性和进行开销限制。有一些算法基于这些特性实现,比如elimination arrays(出自论文Using elimination to implement scalable and lock-free FIFO queues)和optimistic back pointers(出自论文http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf)。但是,双队列的性质使得在需要双性时,可以使用一种更简单的策略来改进m&s这类队列的实现。 15 | 16 | 在双队列中,每个节点必须通过原子操作维护它的状态。我们是这样实现的:对于DATA节点,匹配就是通过CAS操作,把它的item属性从一个非null的值改为null。对于REQUEST节点,匹配就是通过CAS操作把item从null改为非null值。双队列中的元素,通过link操作能变成可用的,通过match操作能变成不可用的。比普通的M&S队列,在入列/出列的时候多了原子操作。 17 | 18 | 一旦节点被匹配,它的匹配状态就不能更改了。我们可以这么安排链表里的节点:前面是0+个匹配过的节点,后面是0+个未匹配的节点。如果不考虑时间和空间性能的话,链表里的节点也可以是乱的(?猜的),遍历所有节点,匹配的时候匹配第一个遇到的未匹配节点,添加(append)的时候把最后一个节点的next指向新节点。但这不是个好方法,唯一的优点是改变head/tail节点的时候不用原子操作。 19 | 20 | (未完待续...) 21 | -------------------------------------------------------------------------------- /Mysql_InnoDB笔记一览.md: -------------------------------------------------------------------------------- 1 | ![Mysql_InnoDB笔记一览](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/Mysql_InnoDB%E7%AC%94%E8%AE%B0%E4%B8%80%E8%A7%88.jpg "Mysql_InnoDB笔记一览") 2 | -------------------------------------------------------------------------------- /Mysql笔记一览.md: -------------------------------------------------------------------------------- 1 | ![Mysql笔记一览](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/Mysql%E7%AC%94%E8%AE%B0%E4%B8%80%E8%A7%88.jpg "Mysql笔记一览") 2 | -------------------------------------------------------------------------------- /PHP,Java和Python的字符串匹配算法(模式匹配).md: -------------------------------------------------------------------------------- 1 | 数据结构和算法书一般会介绍KMP算法,其实KMP算法的性能并不好。查看Java源码和PHP源码后,发现他们使用了如下的匹配算法。 2 | 3 | 各语言使用的匹配算法 4 | - Java使用的是朴素匹配。 5 | - 为什么java String.contains 没有使用类似KMP字符串匹配算法进行优化? https://www.zhihu.com/question/27852656 6 | - PHP使用的是首尾匹配法。php7开始,源字符串(haystack)大于等于1024并且目标字符串(needle)大于等于9,会用Sunday算法。 7 | - zend_memnstr。用于字符串匹配。首尾匹配算法。在Zend/zend_operators.h。 8 | - zend_memnstr_ex。用于字符串匹配。 Sunday算法。在Zend/zend_operators.c 9 | - Python使用简化的Boyer-Moore算法,并且结合了Horspool和Sunday的一些思路。源码在Objects/stringlib/fastsearch.h。算法介绍 http://effbot.org/zone/stringlib.htm 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 用通俗易懂的语言解释技术,俗称大白话。 2 | 3 | 主要从以下几点分析技术: 4 | - 应用。怎么使用。 5 | - 概念/约定/设计。 6 | - 流程。 7 | - 功能。实现的功能;为实现功能做的事情。 8 | - 性能。该技术为提高性能做的事情;应用时可以提高性能的做法。 9 | - 问题。该技术遇到的问题和解决方案;应用时遇到的问题和解决方案。 10 | - 安全。该技术为了安全做的事情。应用时遇到的安全问题和解决方案。 11 | -------------------------------------------------------------------------------- /Redis内部数据结构.md: -------------------------------------------------------------------------------- 1 | ![Redis内部数据结构](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/Redis%E5%86%85%E9%83%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.jpg "Redis内部数据结构") 2 | -------------------------------------------------------------------------------- /Redis笔记一览.md: -------------------------------------------------------------------------------- 1 | ![Redis笔记一览](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/Redis%E7%AC%94%E8%AE%B0%E4%B8%80%E8%A7%88.jpg "Redis笔记一览") 2 | -------------------------------------------------------------------------------- /images/FastDFS笔记一览.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/FastDFS笔记一览.jpg -------------------------------------------------------------------------------- /images/Java笔记一览.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/Java笔记一览.jpg -------------------------------------------------------------------------------- /images/Mysql_InnoDB笔记一览.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/Mysql_InnoDB笔记一览.jpg -------------------------------------------------------------------------------- /images/Mysql笔记一览.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/Mysql笔记一览.jpg -------------------------------------------------------------------------------- /images/PHP_核心原理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/PHP_核心原理.png -------------------------------------------------------------------------------- /images/Redis内部数据结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/Redis内部数据结构.jpg -------------------------------------------------------------------------------- /images/Redis笔记一览.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/Redis笔记一览.jpg -------------------------------------------------------------------------------- /images/java数据结构总结.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/java数据结构总结.jpg -------------------------------------------------------------------------------- /images/readme.md: -------------------------------------------------------------------------------- 1 | 存图片的地方 2 | -------------------------------------------------------------------------------- /images/算法和数据结构笔记一览.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/images/算法和数据结构笔记一览.jpg -------------------------------------------------------------------------------- /linux_sort命令.md: -------------------------------------------------------------------------------- 1 | https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html#sort-invocation 2 | 功能: 3 | - 以数字排序。 4 | - 随机顺序排序。 5 | - 指定用来排序的字符范围,从第几列的第几个字符开始,到第几列的第几个字符。 6 | - 忽略行首的空格字符。 7 | - 忽略字符数字空格外的字符。 8 | - 小写当作大写。 9 | - 按照数值排序。 10 | - 逆序。 11 | - 指定分隔符,默认是空白。 12 | - 设置初始缓冲区大小。 13 | - 可以指定临时文件目录。可以指定多个临时文件目录,临时文件会保存在所有目录里,给IO瓶颈的排序操作指定不同磁盘或控制器的临时目录,可以提高性能。 14 | - 指定线程数。 15 | - 以双精度浮点数排序。 16 | - 以人类可读的字符排序,比如10k/2.2G。 17 | - 以英文月份排序。 18 | - 使用prog压缩临时文件。 19 | - 指定多个顺序。 20 | - 把结果输出到文件。 21 | - 过滤掉重复的。 22 | 23 | ``` 24 | sort -n #数字排序 25 | sort -k 1.2,1.2 #指定用来排序的字符范围,从第几列的第几个字符开始,到第几列的第几个字符。 26 | sort -r #逆序 27 | sort -u #过滤掉重复的。 28 | sort -b #忽略行首的空格字符 29 | sort -d #忽略字符数字空格外的字符 30 | sort -t : #冒号分隔 31 | sort --parallel=4 #4个线程 32 | sort -H #以人类可读的字符排序,比如10k/2.2G。 33 | sort -s -t '.' -k 1,1n -k 2,2n -k 3,3n -k 4,4n #IP排序 34 | ``` 35 | -------------------------------------------------------------------------------- /linux_查看编码和转码.md: -------------------------------------------------------------------------------- 1 | **查看文件编码** 2 | 1. 在Vim 中可以直接查看 文件 编码 3 | - :set fileencoding 4 | 2. enca(如果你的系统中没有安装这个命令,可以用sudo yum install -y enca 安装 ) 5 | - enca filename 6 | - enca -L zh_CN filename 7 | 8 | **文件转码** 9 | 10 | 1. 在Vim中直接进行转换文件 编码 ,比如将一个文件 转换成utf-8格式 11 | - :set fileencoding=utf-8 12 | 2. enconv 转换文件 编码 ,比如要将一个GBK编码 的文件 转换成UTF-8编码 ,操作如下 13 | - enconv -L zh_CN -x UTF-8 filename 14 | 3. iconv 转换,iconv的命令格式如下: 15 | - iconv -f encoding -t encoding inputfile 16 | - 比如将一个UTF-8 编码 的文件 转换成GBK编码 iconv -f GBK -t UTF-8 file1 -o file2 17 | -------------------------------------------------------------------------------- /markdown基本语法.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derogithub/dabaihua/3f3cb1197450699eb61e0b32f184eb2bca0612ba/markdown基本语法.png -------------------------------------------------------------------------------- /markdown语法.md: -------------------------------------------------------------------------------- 1 | # 一级标题 2 | ## 二级标题 3 | ### 三级标题 4 | #### 四级标题 5 | ##### 五级标题 6 | ###### 六级标题 7 | 8 | **加粗** 普通 *斜体* ~~划掉~~ 9 | 10 | [链接](http://www.jianshu.com "鼠标移上来显示") 11 | 12 | - 无序列表1 13 | - 无序列表2 14 | - 无序列表3 15 | 16 | 1. 有序列表1 17 | 2. 有序列表2 18 | 4. 有序列表3 19 | 20 | - [x] 任务列表 21 | - [x] 已完成任务 22 | - [ ] 未完成任务 23 | 24 | ![图片无法显示时显示的文字](https://www.baidu.com/favicon.ico "鼠标移上来显示") 25 | 26 | ------------------- 27 | ↑分割线 28 | 29 | > 一级引用 30 | >> 二级引用 31 | >>> 三级引用 32 | 33 | |表格|表头|左对齐左对齐|右对齐右对齐|居中居中| 34 | |---|----|:-----|-----:|:--:| 35 | |表格|表格|左对齐|右对齐|居中| 36 | |表格|表格|左对齐|右对齐|居中| 37 | |表格|表格|左对齐|右对齐|居中| 38 | 39 | 40 | ``` javascript 41 | var str = "js代码" 42 | ``` 43 | ``` php 44 | $str = "php代码"; 45 | ``` 46 | 一句话中间的代码`String str = "java代码"` 47 | 48 | 邮箱 49 | -------------------------------------------------------------------------------- /php中的trait.md: -------------------------------------------------------------------------------- 1 | trait(特性)。为了代码复用。是一种组合的方式,比继承更灵活。相当于把trait中的代码拷贝了过来,除了抽象方法是需要实现的。 2 | #### 概念/约定/设计 3 | - 同名方法优先级 当前类的->trait的->继承的 4 | - 类中属性和trait中属性同名时,除非访问控制和初始值相同,否则都会报fatal error。访问控制和初始值相同,7.0之前报E_STRICT。 5 | #### 应用 6 | - 定义 7 | - 定义。triat中可以有属性和方法。trait TraitName {} 8 | - 可以定义trait中方法和属性的访问控制(private/protected/public),在类中调用trait后,所有方法和属性都会引入进来。(相当于把trait中的代码拷贝了过来。) 9 | - 在triat中定义抽象方法。调用trait的类必须实现。这里就不能相当于把trait中的代码拷贝了过来了。abstract public function funcName(); 10 | - 可以定义静态方法和属性。 11 | - 调用 12 | - 在类中/trait中 use TraitName; 13 | - 多个 use TraitName1, TraitName2; 14 | - 修改trait中方法的访问控制(private/protected/public) 。use TraitName { funcName as protected; } 15 | - 给trait中方法加别名。原名还可以用。 use TraitName { funcName as aliasName; } 16 | - 给trait中方法加别名,并且指定别名的访问控制。原名的访问控制不受影响。use TraitName { funcName as private aliasName; } 17 | - 多个trait中有重名方法,仅使用其中1个。指定1个替代另一个:use TraitName1, TraitName2 { TraitName1::funcName insteadof TraitName2; } 18 | - 多个trait中有重名方法,两个都要使用。指定1个替代另一个,给另一个指定别名:use TraitName1, TraitName2 { TraitName1::funcName insteadof TraitName2; TraitName2::funcName as aliasName; } 19 | -------------------------------------------------------------------------------- /php利用位运算做权限.md: -------------------------------------------------------------------------------- 1 | - 增加权限 2 | - 用"|"运算. 3 | - 二进制数相当于加. 如1 | 2得到3(1+2=3). 4 | - 非二进制数如3 | 7得到7(3和7所包含的二级制数并集的和,3=1+2,7=1+2+4,3 | 7 = 1+2+4) 5 | - 删除权限 6 | - E_ALL & ~E_NOTICE 7 | - E_ALL ^ E_NOTICE 8 | - 验证权限 9 | - if ( $a & $b ) 10 | - $a是二进制数,$a & $b大于0,说明$b有$a的权限 11 | - if ( $a == ($a & $b) ) 12 | - $a是非二进制数,表达式为真,说明$b有$a的权限 13 | - 设置权限 14 | - 1 << 1 为 2 15 | - 1 << 2 为 4 16 | - 1 << 3 为 8 17 | -------------------------------------------------------------------------------- /php命名空间.md: -------------------------------------------------------------------------------- 1 | ### 命名空间 2 | 针对类(包括抽象类和traits)/接口/函数/常量 3 | #### 应用 4 | - namespace MyProject\Sub\Level; 5 | - 大括号定义 6 | ``` php 7 | namespace MyProject { 8 | const CONNECT_OK = 1; 9 | class Connection { /* ... */ } 10 | function connect() { /* ... */ } 11 | } 12 | ``` 13 | - 所有代码之前声明 14 | - 多个文件可以共用1个 15 | - 1个文件中可定义多个命名空间 16 | - 在已定义命名空间的文件中,写全局代码。 17 | ``` php 18 | namespace { // 全局代码 19 | session_start(); 20 | $a = MyProject\connect(); 21 | echo MyProject\Connection::start(); 22 | } 23 | ``` 24 | - 当前空间是指代码所在文件的空间,而不是执行时所在的空间。 25 | - 获取当前空间的字符串 \_\_NAMESPACE\_\_ 26 | - 调用 27 | - 调用当前空间下的 foo(); 或namespace\foo(); 28 | - 调用当前子空间下的 sub\foo(); 或 namespace\sub\foo(); 29 | - 调用指定空间下的 \xxx\foo(); 30 | - 调用全局的 \foo(); 31 | - 在动态语言中使用,如$a = '\Sub\ClassName'; $classObj = new $a; 要用完全限定名称(绝对路径),因为自动补全是在编译期间完成的。开头没有\的会自动加上。双引号要转义"\\\\namespacename\\\\classname" 32 | - 别名 33 | - 设置空间的别名 use My\Full as Another; 或use My\Full,默认别名就是Full 34 | - 设置类的别名 use My\Full\Classname as Another; 或 use My\Full\Classname,默认别名就是Classname 35 | - 设置函数方法的别名,5.6起。use function My\Full\functionName as func; 或use function My\Full\functionName,默认别名就是functionName 36 | - 设置常量的别名,5.6起。use const My\Full\CONSTANT 37 | #### 功能 38 | - 避免类(包括抽象类和traits)/接口/函数/常量命名冲突。 39 | - 可以设置别名。用于提高代码易读性。 40 | - 实现: 41 | - 导入命名空间: 编译期间,存1个哈希表:FC(imports),如FC(imports)["cc"] = "aa\bb\cc\dd"。在使用类、函数和常量时会把名称按"\"分割,然后以第一节为key查找FC(imports),如果找到了则将FC(imports)中保存的名称与使用时的名称拼接在一起,组成完整的名称。实际上这种机制是把完整的名称切割缩短然后缓存下来,使用时再拼接成完整的名称,也就是内核帮我们组装了名称,对内核而言,最终使用的都是包括完整namespace的名称。 42 | - 导入类: 导入的名称保存在FC(imports)中,与空间不同的是不会根据""切割后的最后一节检索,而是直接使用类名查找 43 | - 导入函数: 通过use function导入到FC(imports_function),补全时先查找FC(imports_function),如果没有找到则继续按照a的情况处理 44 | - 导入常量: 通过use const导入到FC(imports_const),补全时先查找FC(imports_const),如果没有找到则继续按照a的情况处理 45 | 数据结构 46 | ``` c 47 | typedef struct _zend_file_context { 48 | ... 49 | //用于保存导入的类或命名空间 50 | HashTable *imports; 51 | //用于保存导入的函数 52 | HashTable *imports_function; 53 | //用于保存导入的常量 54 | HashTable *imports_const; 55 | } zend_file_context; 56 | ``` 57 | -------------------------------------------------------------------------------- /php对象的赋值&clone&引用&比较.md: -------------------------------------------------------------------------------- 1 | 对象的赋值/clone/引用/比较。对象的变量存了一个标识符,类似指针,指向一个对象。 2 | - 赋值。$obj2 = $obj1; 两个指向同一个对象 3 | - clone。$obj2 = clone $obj1; 分别指向两个对象。但如果属性是对象,如$obj1->subObj1,$obj2->subObj1,仍然指向同一个对象,这叫做浅复制。想要属性分别指向两个对象,需要自己在__clone()里实现。 4 | - 引用。$obj2 = &$obj1; 两个指向同一个引用,这个引用指向一个对象。之前是:变量->对象,现在是:变量->引用->对象。 5 | - 比较。==比较类/属性名/属性值。===比较是否指向同一个对象,赋值和引用就是指向同一个对象。 6 | -------------------------------------------------------------------------------- /php扩展_xhprof.md: -------------------------------------------------------------------------------- 1 | 英文文档: http://web.archive.org/web/20110514095512/http://mirror.facebook.net/facebook/xhprof/doc.html 2 | 3 | XHPGUI: https://github.com/preinheimer/xhprof 4 | 5 | 简介 6 | - XHProf 是一个轻量级的分层性能测量分析器。 在数据收集阶段,它跟踪调用次数与测量数据,展示程序动态调用的弧线图。 它在报告、后期处理阶段计算了独占的性能度量,例如运行经过的时间、CPU 计算时间和内存开销。 函数性能报告可以由调用者和被调用者终止。 在数据搜集阶段 XHProf 通过调用图的循环来检测递归函数,通过赋予唯一的深度名称来避免递归调用的循环。 7 | - XHProf 包含了一个基于 HTML 的简单用户界面(由 PHP 写成)。 基于浏览器的用户界面使得浏览、分享性能数据结果更加简单方便。 同时也支持查看调用图。 8 | - XHProf 的报告对理解代码执行结构常常很有帮助。 比如此分层报告可用于确定在哪个调用链里调用了某个函数。 9 | - XHProf 对两次运行进行比较(又名 "diff" 报告),或者多次运行数据的合计。 对比、合并报告,很像针对单次运行的“平式视图”性能报告,就像“分层式视图”的性能报告。 10 | 11 | php.ini 12 | ``` 13 | extension=xhprof.so 14 | xhprof.output_dir=/web/xhprof/output 储存 XHProf 运行数据的默认目录,用于接口 iXHProfRuns(即 XHProfRuns_Default 类)。 15 | ``` 16 | 17 | 常量 18 | - XHPROF_FLAGS_NO_BUILTINS 使得跳过所有内置(内部)函数。 19 | - XHPROF_FLAGS_CPU 使输出的性能数据中添加 CPU 数据。 20 | - XHPROF_FLAGS_MEMORY 使输出的性能数据中添加内存数据。 21 | 22 | 函数 23 | - void xhprof_enable([ int $flags = 0 [, array $options ]] ) 开始统计.$flags标记需要统计的额外信息(见xhprof常量);$options可设置忽略统计的函数:array('ignored_functions' => array('trim','substr')) 24 | - array xhprof_disable( void ) 停止统计.返回统计结果. 25 | - xhprof_sample_enable() 轻量级统计开始.xhprof_enable() 的更轻量的版本,以采样模式开始性能分析。 抽样的间隔为 0.1 秒,样本记录了完整的函数调用堆栈。 主要使用的情况是以较低的性能开销来进行性能监控和诊断。 26 | - xhprof_sample_disable() 停止采样模式的 xhprof 分析器。 27 | 28 | 参数详解: 29 | 名词: 30 | - Function Name 函数名 31 | - Calls 调用次数 32 | - Calls% 调用百分比 33 | - Incl. Wall Time (microsec) 调用的包括子函数所有花费时间 以微秒算(一百万分之一秒) 34 | - IWall% 调用的包括子函数所有花费时间的百分比 35 | - Excl. Wall Time (microsec) 函数执行本身花费的时间,不包括子树执行时间,以微秒算(一百万分之一秒) 36 | - EWall% 函数执行本身花费的时间的百分比,不包括子树执行时间 37 | - Incl. CPU(microsecs) 调用的包括子函数所有花费的cpu时间。减Incl. Wall Time即为等待cpu的时间 38 | - 减Excl. Wall Time即为等待cpu的时间 39 | - ICpu% Incl. CPU(microsecs)的百分比 40 | - Excl. CPU(microsec) 函数执行本身花费的cpu时间,不包括子树执行时间,以微秒算(一百万分之一秒)。 41 | - ECPU% Excl. CPU(microsec)的百分比 42 | - Incl.MemUse(bytes) 包括子函数执行使用的内存。 43 | - IMemUse% Incl.MemUse(bytes)的百分比 44 | - Excl.MemUse(bytes) 函数执行本身内存,以字节算 45 | - EMemUse% Excl.MemUse(bytes)的百分比 46 | - Incl.PeakMemUse(bytes) Incl.MemUse的峰值 47 | - IPeakMemUse% Incl.PeakMemUse(bytes) 的峰值百分比 48 | - Excl.PeakMemUse(bytes) Excl.MemUse的峰值 49 | - EPeakMemUse% EMemUse% 峰值百分比 50 | 51 | 使用范例 52 | ``` php 53 | save_run($xhprof_data, "xhprof_testing"); 68 | 69 | echo "http://localhost/xhprof/xhprof_html/index.php?run={$run_id}&source=xhprof_testing\n"; 70 | 71 | ?> 72 | ``` 73 | 74 | -------------------------------------------------------------------------------- /php排序函数.md: -------------------------------------------------------------------------------- 1 | php排序。php的排序都用的快速排序。 2 | - sort 根据值正向排序,重建索引。可指定数组值当作数字或字符串比较。可设置不区分大小写。使用快速排序算法。 3 | - rsort 根据值逆向排序,重建索引。可指定数组值当作数字或字符串比较。可设置不区分大小写。 4 | - ksort 根据键名正向排序,保留索引。 5 | - krsort 根据键名逆向排序,保留索引。 6 | - asort 根据值正向排序,保留索引。 7 | - arsort 根据值逆向排序,保留索引。 8 | - usort 根据值自定义排序,重建索引。在第一个参数小于,等于或大于第二个参数时,该比较函数必须相应地返回一个小于,等于或大于 0 的整数。 9 | - uksort 根据键名自定义排序,保留索引。 10 | - uasort 根据值自定义排序,保留索引。 11 | - natsort 根据值自然排序,保留索引。自然排序,就是值里”字符串“部分按a-z排,”数字“部分按0-9排。如a < a0 < a1 < a1a < a1b < a2 < a10 < a20,如x2-g8 < x2-y7 < x2-y08 < x8-y8, 12 | - natcasesort 根据值自然排序,保留索引,不区分大小写。 13 | -------------------------------------------------------------------------------- /php核心原理笔记一览.md: -------------------------------------------------------------------------------- 1 | ![php核心原理笔记一览](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/PHP_%E6%A0%B8%E5%BF%83%E5%8E%9F%E7%90%86.png "php核心原理笔记一览") 2 | -------------------------------------------------------------------------------- /php的session.md: -------------------------------------------------------------------------------- 1 | **应用** 2 | - 不要使用 unset($_SESSION) 来复位超级变量 $_SESSION,这样会导致无法继续在 $_SESSION 中注册会话变量。 3 | - 不可以将引用保存到session,因为无法将一个引用恢复到另外一个变量。 4 | - 同1个sessionid并发请求时,会因为session文件的锁而不能读取session数据。 5 | 1. 解决方案1:用完session后尽快调用session_write_close()来释放锁。 6 | 2. 解决方案2:使用支持并发操作的会话保存管理器来替代文件会话保存管理器。 7 | 8 | **流程** 9 | - session流程 10 | 1. 当开始一个会话时(设置了自动开启或调用session_start()),PHP 会尝试从请求中查找会话 ID (通常通过会话 cookie) 11 | 2. 如果请求中不包含会话 ID 信息,PHP 就会创建一个新的会话。 12 | 3. 会话开始之后,PHP 就会将会话中的数据设置到 $_SESSION 变量中。 13 | 4. 当PHP停止或调用session_write_close()关闭会话的时候,它会自动读取 $_SESSION 中的内容,并将其进行序列化, 然后发送给会话保存管理器来进行保存。 14 | - 自定义会话管理器 15 | 1. 会话开始的时候,PHP 会调用 open 管理器 16 | 2. 然后再调用 read 回调函数来读取内容,该回调函数返回已经经过编码的字符串。 然后 PHP 会将这个字符串解码,并且产生一个数组对象,然后保存至 $_SESSION 超级全局变量。 17 | 3. 当 PHP 关闭的时候(或者调用了 session_write_close() 之后), PHP 会对 $_SESSION 中的数据进行编码, 然后和会话 ID 一起传送给 write 回调函数。 18 | 4. 之后,PHP 内部将调用 close 回调函数。 19 | 5. 销毁会话时,PHP 会调用 destroy 回调函数。 20 | 21 | 根据会话生命周期时间的设置,PHP 会不时地调用 gc 回调函数。 22 | 23 | **功能** 24 | - 指定session处理器。session.save_handler 25 | - 指定session文件路径。session.save_path,默认/tmp 26 | - 指定session文件目录层级。用于session文件过多时分目录存放。每层64个目录,需要用ext/session/mod_files.sh先创建好目录。 27 | - 指定cookie中sessionid的名字。session.name,默认为 PHPSESSID 28 | - 自动开启。session.auto_start 29 | - 指定session序列化方式。session.serialize_handler,默认php,5.5.4 起可以用php_serialize。 30 | - 设置gc的概率。默认每请求1/100的概率启动gc。session.gc_probability/session.gc_divisor 31 | - 设置session过期时间。过期后可以被gc清除,但不是立即清除。session.gc_maxlifetime 32 | - 设置是否用cookie保存sessionid。session.use_cookies,默认1。 33 | - 指定存sessionid的cookie的过期时间/路径/域名。session.cookie_lifetime,默认0(浏览器关闭后过期)。session.cookie_path,默认/。session.cookie_domain。 34 | - 通过设置header中的Expires/Cache-Control/Last-Modified,来告诉浏览器/代理服务器如何缓存页面。session_cache_limiter,设置缓冲模式。session.cache_expire,设置缓存时间。 35 | - 允许在url参数/form表单中传sessionid。session.use_trans_sid,默认0(关闭)。session.trans_sid_tags(7.1.0起)或url_rewriter.tags(7.1.0前),哪些html标签的url要传。trans_sid_hosts,哪些域名的url要传。 36 | - session文件加锁。基于文件的session存储, 在会话开始的时候都会给会话数据文件加锁, 直到PHP脚本执行完毕或者显式调用session_write_close()(别名session_commit)来保存会话数据。 在此期间,其他脚本不可以访问同一个会话数据文件。 37 | 38 | **性能** 39 | - 用户并发请求时,基于文件的session被锁。可以在开启session的时候指定只读,session_start(['read_and_close'=>1])。可以尽早释放锁,调用session_write_close()(别名session_commit)。 40 | 41 | **问题** 42 | - $_SESSION的索引不能用数字也不能包含特殊字符(| and !)。解决方案:session序列化用php_serialize。session.serialize_handler 43 | 44 | **安全** 45 | - 服务器上的其他用户有可能通过session目录的文件列表破解会话。解决方案:修改session目录的权限。 46 | - 检查referer,如果referer不包含session.referer_check设置的值,把sessionid标记为无效。 47 | - 为防止暴力碰撞sessionid, 48 | * 7.1.0起可以设置更长更复杂的sessionid。session.sid_length,默认32。session.sid_bits_per_character,每个字符存多少bit。 49 | * php5开始可以设置哈希算法。session.hash_function,默认0(0 md5,1 sha1),5.3.0起支持hash扩展可用的哈希算法。 50 | * session.hash_bits_per_character,允许用户定义将二进制散列数据转换为可读的格式时每个字符存放多少个比特。 51 | * 设置sessionid生成时用到的随机数,可以使sessionid更随机,从而更安全。session.entropy_file指定文件,5.4.0起默认用/dev/random或/dev/urandom。session.entropy_length指定读取的字节数,默认0(禁用)。 52 | * 7.1.0起可以用session_create_id([ string $prefix ])生成无碰撞的sessionid(会做碰撞检测,具体见官方文档)。同时可以给sessionid设置1个前缀如用户id,可以通过检查前缀判断是否和用户匹配。 53 | - 为防止攻击者随意发送sessionid,不接受服务器没生成过的sessionid。开启session.use_strict_mode后,收到没生成过的sessionid,就生成一个发给浏览器。 54 | - 情形1:攻击者可以通过邮件给受害者发送一个包含会话 ID 的链接: http://example.com/page.php?PHPSESSID=123456789。 如果启用了 session.use_trans_sid 配置项, 那么受害者将会使用攻击者所提供的会话 ID 开始一个新的会话。 如果启用了 session.use_strict_mode 选项,就可以降低风险。 55 | - 为防止有关通过URL传递sessionid的攻击,指定只能用cookie存sessionid。session.use_only_cookies,5.3.0起默认1。 56 | - 隐患1:如果在 URL 中包含了会话 ID, 并且访问了外部的站点, 那么你的会话 ID 可能在外部站点的访问日志中被记录(referrer 请求头)。 57 | - 攻击者获得服务器生成的sessionid后,用js注入等手段让用户用这个sessionid,这时候攻击者知道用户用了那个sessionid。 58 | - 如果你已经启用了 session.use_strict_mode 配置项, 同时使用基于时间戳的会话管理, 并且通过设置 session_regenerate_id() 配置项 来重新生成会话 ID, 那么,攻击者生成的会话 ID 就可以被删除掉了。 当发生对过期会话访问的时候, 你应该保存活跃会话的所有数据, 以备后续分析使用。 然后让用户退出当前的会话,并且重新登录。 防止攻击者继续使用“偷”来的会话。 59 | - 如果必须启用session.use_trans_sid。可以通过session_regenerate_id([ bool $delete_old_session = false ])在每次请求都生成1个新的sessionid。可以选择是否立即删除原sessionid的数据。 60 | - 立即删除旧session出现问题1:网络不稳定或用户并发请求时,旧session被删除,但用户没有接到新sessionid。可能导致会话丢失或会话数据不一致。解决方案:不立即删除旧session。在旧session中自己存1个时间戳,自己设定一个可接受的过期时间。在这个时间范围内,如果接收到旧sessionid,仍可以使用数据如登录状态。也可以在旧session中存新sessionid,时间范围内把sessionid设置为新sessionid。如果超出时间范围,就手动删掉旧session中的隐私数据。具体见 http://php.net/manual/zh/function.session-regenerate-id.php 61 | - 不立即删除旧session出现问题2:如果sessionid被攻击者得到,会不安全。 62 | - 为防止网络监听获取sessionid,可设置仅通过https传存sessionid的cookie,由浏览器来控制。Chrome52/Firefox52起,仅通过https可以设置secure的cookie。session.cookie_secure 63 | - 为防止XSS攻击,设置存session的cookie只能被http协议访问,js不能获取。浏览器会控制访问权限。session.cookie_httponly 64 | - 拒绝服务攻击 65 | - 情形1:攻击者设置了不可删除的 cookie 66 | - 情形2:攻击者并发请求,基于文件的session一直处于锁定状态 67 | - 即使用HTTPS协议,CRIME 和 BEAST 漏洞可以使得攻击者读取到你的数据。 68 | - 即使用HTTPS协议,HTTPS MITM(中间人攻击),可以窃取 HTTPS 协议下的通信数据。 69 | - 基于session自动登录有风险。 70 | - 减少风险方法1:自己实现自动登录机制,而不是仅仅依据sessionid。 71 | - 减少风险方法2:用于自动登录的数据是一次性的。 72 | 73 | 74 | -------------------------------------------------------------------------------- /php的自动加载.md: -------------------------------------------------------------------------------- 1 | - 两种方式。先spl_autoload_register(),后__autoload() 2 | - 实现:类的自动加载实际就是定义了一个钩子函数,实例化类时如果在EG(class_table)中没有找到对应的类则会调用这个钩子函数,调用完以后再重新查找一次。这个钩子函数保存在EG(autoload_func)中。 3 | - spl_autoload_register([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]])。可多个加载器。 4 | - 实现:spl创建了一个队列来保存用户注册的加载器,然后定义了一个spl_autoload函数到EG(autoload_func),当找不到类时内核回调spl_autoload,这个函数再依次调用用户注册的加载器,没调用一个重新检查下查找的类是否在EG(class_table)中已经注册,仍找不到的话继续调用下一个加载器,直到类成功注册为止。 5 | - __autoload()。1个加载器。 6 | -------------------------------------------------------------------------------- /php的配置.md: -------------------------------------------------------------------------------- 1 | **PHP的配置。php.ini** 2 | 3 | - 配置文件: http://www.php.net/manual/zh/configuration.file.php 4 | - 配置可被设定范围: http://www.php.net/manual/zh/configuration.changes.modes.php 5 | - php.ini 配置选项列表: http://www.php.net/manual/zh/ini.list.php 6 | - 怎样修改配置设定: http://www.php.net/manual/zh/configuration.changes.php 7 | - PHP 配置 open_basedir(说明了优先级问题): http://www.cnblogs.com/ybbqg/archive/2012/05/04/2482479.html 8 | 9 | - 配置文件(php.ini)在 PHP 启动时被读取。对于服务器模块版本的 PHP,仅在 web 服务器启动时读取一次。对于 CGI 和 CLI 版本,每次调用都会读取。 10 | - 如果存在 php-SAPI.ini(SAPI 是当前所用的 SAPI 名称,因此实际文件名为 php-cli.ini 或 php-apache.ini 等),则会用它替代 php.ini。SAPI 的名称可以用 php_sapi_name() 来测定。 11 | - 优先级 12 | - 配置参数优先级:服务器(httpd.conf或php-fpm.conf) > 文件内设置(ini_set) > php.ini 13 | - httpd.conf里配置优先级:Direcotry里 > VirtualHost里,或.htaccess 14 | - php.ini 的搜索路径如下(按顺序): 15 | 1. SAPI 模块所指定的位置(Apache 2 中的 PHPIniDir 指令,CGI 和 CLI 中的 -c 命令行选项,NSAPI 中的 php_ini 参数,THTTPD 中的 PHP_INI_PATH 环境变量)。 16 | 2. PHPRC 环境变量。在 PHP 5.2.0 之前,其顺序在以下提及的注册表键值之后。 17 | 3. 自 PHP 5.2.0 起,可以为不同版本的 PHP 指定不同的 php.ini 文件位置。将以下面的顺序检查注册表目录:[HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y.z],[HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y] 和 [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x],其中的 x,y 和 z 指的是 PHP 主版本号,次版本号和发行批次。如果在其中任何目录下的 IniFilePath 有键值,则第一个值将被用作 php.ini 的位置(仅适用于 windows)。 18 | 4. [HKEY_LOCAL_MACHINE\SOFTWARE\PHP] 内 IniFilePath 的值(Windows 注册表位置)。 19 | 5. 当前工作目录(对于 CLI)。 20 | 6. web 服务器目录(对于 SAPI 模块)或 PHP 所在目录(Windows 下其它情况)。 21 | 7. Windows 目录(C:\windows 或 C:\winnt),或 --with-config-file-path 编译时选项指定的位置。 22 | 23 | -------------------------------------------------------------------------------- /php魔术方法.md: -------------------------------------------------------------------------------- 1 | 魔术方法。就是设置当以某种方式使用类或对象时,类和对象的行为。 2 | 3 | - __construct() 当创建这个类的对象时调用。子类没有定义会调用父类的,子类有可以用parent::__construct()调用父类的。 用于初始化对象。 4 | - __destruct() 当这个类的对象的所有引用都被删除/对象被显示销毁/脚本关闭/exit()退出时调用。子类没有定义会调用父类的,子类有可以用parent::__destruct()调用父类的。 5 | - __call() 当调用对象的一个不可访问的方法时调用。比如private方法/没有的方法。参数是方法名和方法参数__call(string $name , array $arguments) 6 | - __callStatic() 当调用类的一个不可访问的静态方法时调用。比如private方法/没有的方法。参数是方法名和方法参数__callStatic(string $name , array $arguments) 。5.3.0起。 7 | - __get() 当读取对象的不可访问的属性时调用。比如private属性/没有的属性。可以返回值。参数是属性名__get(string $name) 8 | - __set() 当给对象的不可访问的属性赋值时调用。比如private属性/没有的属性。参数是属性名__set(string $name, mixed $value) 9 | - __isset() 当isset()或empty()对象的不可访问的属性时调用。返回bool。参数是属性名__isset(string $name) 10 | - __unset() 当unset()对象的不可访问的属性时调用。参数是属性名__unset(string $name) 11 | - __toString() 当把对象当作字符串使用时调用。如echo/print/printf。返回一个字符串。 12 | - __invoke() 当把对象当作函数使用时调用。如$obj($str); 13 | - __clone() 当用clone来复制对象时调用。用于自己完成深度复制,比如有属性是对象就clone一下,有属性是引用就重新赋值。 14 | - __sleep() 当serialize()这个类的对象时调用。用于返回一个想被序列化的属性的数组,如果什么也不返回就序列化null。 15 | - __wakeup() 当unserialize()这个类的对象时调用。用于初始化操作,比如建立数据库链接。反序列化可以看作new了一个对象。 16 | - __set_state() 当用var_export()打印类的对象时调用。参数是数组形式的对象属性__set_state(array $properties) 。用于返回一个用来打印的对象。 17 | - __debugInfo() 当用var_dump()打印类的对象时调用。用于返回一个用来打印的数组。5.6.0起。 18 | -------------------------------------------------------------------------------- /如何技术选型.md: -------------------------------------------------------------------------------- 1 | 技术选型 2 | - 开发效率优先还是运行效率优先 选择开发效率还是执行效率是个老生常谈的问题。对于不同阶段的公司和项目会有不同的选择。新的商业项目更趋向于选择开发效率优先。因为商业模式的尽早验证比其他因素更重要。但是假如是成熟的商业模式,预见规模会很快扩大到很大,则可以选择运行效率优先。另规模化项目比如云服务平台、大公司的基础组件更趋向于选择运行效率优先。 3 | - 成熟的小众技术 有一些小众技术及时诞生了很多年,由于适用性比较窄,也不广为人知。但是这不意味着这种技术不成熟。Erlang、Lisp、Lua、Node.js 都是成熟的小众技术。成熟的小众技术解决特定领域问题非常高效。 4 | - 社区/使用人群 5 | - 长期支持 技术的生命周期必须显著长于项目的生命周期;核心作者全职;独立运作的基金会来负责语言的长期维护;公开透明的决策机制来决定语言的未来; 6 | - 缺陷 需要时间和使用人群才能暴露出来; 7 | - 优化空间 8 | - 亲身体验 9 | - 列出多种方案 10 | - 了解候选方案的产生背景 11 | - 有能力修复bug 12 | - 当下最稳定最成熟的技术 13 | 14 | 参考 15 | - 互联网公司和团队的技术选型:http://www.admin10000.com/document/6388.html 16 | - 技术选型案例 http://www.jianshu.com/p/7409866426ec 17 | - 如何做好企业/团队的技术选型? http://history.programmer.com.cn/8514/ 18 | - 谈谈技术选型:http://www.infoq.com/cn/news/2017/02/Technology-selection 19 | 20 | -------------------------------------------------------------------------------- /微服务优缺点.md: -------------------------------------------------------------------------------- 1 | **优点** 2 | - 微服务可以通过不同的编程语言与工具进行开发。 3 | - 单体应用变得复杂,没有人能搞懂它。开发会变的困难。 4 | - 单体应用太大,编译,启动都会耗费很长时间。 5 | - 有的模块是cpu密集型,需要部署在cpu密集型服务器上。有的是内存密集型,部署在内存型服务器上有更好的性能。 6 | 7 | **缺点/需要解决的问题** 8 | - 需要调用链。解决追踪问题麻烦,需要跨越多个项目的问题。58用分布式跟踪系统来跟踪调用链。 9 | - 需要优秀的抽象能力。抽象的不好不能复用 10 | - 需要区别版本 11 | - 需要完整的测试,否则排查问题麻烦,调用方和服务方沟通会降低效率 12 | - 一个叫User的服务,究竟提供多少字段?每个调用方都不同。最终,还是需要调用方来告诉服务方,究竟需要哪些字段。 13 | - 不同语言/框架间,同样的代码需要写多次。带来了代码复用和维护问题。 14 | - 需要服务发现 15 | - 网络延迟/不可靠的网络 16 | - 需要消息队列 17 | - 需要应对异步 18 | - 需要有容错性 19 | - 需要工具解决部署问题,提高部署效率 20 | - 需要保证数据的最后一致性 21 | 22 | **实践中适合服务化的业务** 23 | - 下单管理 24 | - 客户管理 25 | 26 | **参考** 27 | - 微服务的优缺点 http://www.infoq.com/cn/news/2014/06/microservices 28 | - 最后,我们所采取的方式是对整体应用进行模块化(这样就可以在模块间共享代码仓库、部署和代码了,同时依然保持良好的松散耦合的组件)并将一些模块放到自己独立的微服务中来实现独立的部署与管理,当然了,我们只在必要的情况下才这么做。 29 | 30 | -------------------------------------------------------------------------------- /正则表达式.md: -------------------------------------------------------------------------------- 1 | #### 捕获组 2 | - 普通捕获组 (expression) 3 | - 命名捕获组 (?Expression) 4 | - PHP中的命名捕获组 (?PExpression) 5 | 6 | 捕获组编号 7 | - 只有普通捕获组: 从左到右,按照'('出现的顺序,从1开始编号. 8 | - 只有命名捕获组: 从左到右,按照'('出现的顺序,从1开始编号. 9 | - 普通捕获组和命名捕获组混合: 混合方式的捕获组编号,首先按照普通捕获组中“(”出现的先后顺序(环视的括号不算),从左到右,从1开始进行编号,当普通捕获组编号完成后,再按命名捕获组中“(”出现的先后顺序,从左到右,接着普通捕获组的编号值继续进行编号。 10 | 11 | 捕获组反向引用 12 | - 普通捕获组反向引用:\k,通常简写为\number 13 | - 命名捕获组反向引用:\k或者\k'name' 14 | - PHP中: preg_replace()中: 用\\1或$1; 引用后面跟数字字符串,用\${1}1; 15 | 16 | #### 非捕获组 17 | 18 | (?:Expression) 括号内的内容不会出现在捕获结果中. 19 | 1. 使用“|”表示“或”的关系时,用“()”限制范围 20 | - (?:近期|近日) 匹配'近期'或'近日',并且不会出现在捕获结果中. 21 | 2. 使用量词限定一个子表达式整体的匹配次数 22 | - (?::[0-5][0-9]){2} 匹配HH:mm:ss格式时间中的分和秒. 23 | 24 | 辩证的使用 25 | - 一些非常简单的正则中,如果使用了非捕获组,因为要解析这种语法,反而可能会降低匹配效率。 26 | - 一般在较复杂,“()”使用较多的正则表达式中可以考虑使用非捕获组。 27 | 28 | #### 平衡组 29 | - (?'group') 把捕获的内容命名为group,并压入堆栈(Stack) 30 | - (?'-group') 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败 31 | - (?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分 32 | - (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败.(?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败 33 | 34 | 例: 35 | ``` 36 |
this is a
this is b
this is c
b too
a too
37 | 如果想匹配出上面的
this is b
this is c
b too
就可以使用平衡组 38 | ]*>[^<>]*(((?'Open']*>)[^<>]*)+((?'-Open')[^<>]*)+)*(?(Open)(?!)) 39 | ``` 40 | 41 | #### 环视 42 | - (?<=Expression) 逆序肯定环视,表示所在位置左侧能够匹配Expression 43 | - (?[^()]+|(?R))*\)/"匹配"some text (a(b(c)d)e) more text". 57 | 58 | 在每次迭代时, PHP 语法分析器都会将(?R)替换为"/\((?>[^()]+|(?R))*\)/" 59 | 60 | #### 一次性匹配 61 | 62 | (?>表达式) 只匹配一次,不会回溯. 63 | 64 | -------------------------------------------------------------------------------- /算法和数据结构笔记一览.md: -------------------------------------------------------------------------------- 1 | ![算法和数据结构笔记一览](https://raw.githubusercontent.com/derogithub/dabaihua/master/images/%E7%AE%97%E6%B3%95%E5%92%8C%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AC%94%E8%AE%B0%E4%B8%80%E8%A7%88.jpg "算法和数据结构笔记一览") 2 | --------------------------------------------------------------------------------