int preg_match_all ( string pattern, string subject, array matches [, int flags])
在 subject 中搜索所有与 pattern 给出的正则表达式匹配的内容并将结果以 flags 指定的顺序放到 matches 中。
搜索到第一个匹配项之后,接下来的搜索从上一个匹配项末尾开始。
flags 可以是下列标记的组合(注意把 PREG_PATTERN_ORDER 和 PREG_SET_ORDER 合起来用没有意义):
PREG_PATTERN_ORDER
对结果排序使 $matches[0] 为全部模式匹配的数组,$matches[1] 为第一个括号中的子模式所匹配的字符串组成的数组,以此类推。
代码如下 | 复制代码 |
<?php |
本例将输出:
<b>example: </b>, this is a test example: , this is a test
因此,$out[0] 包含匹配整个模式的字符串,$out[1] 包含一对 HTML 标记之间的字符串
对结果排序使 $matches[0] 为全部模式匹配的数组,$matches[1] 为第一个括号中的子模式所匹配的字符串组成的数组,以此类推。(即$matches[0] [0]为全部模式匹配中的每一项,$matches[0] [1]为全部模式匹配中的第二项,$matches[1] [0]为匹配每一个括号中的第一项,$matches[1] [0]为匹配每一个括号中的第二项)
代码如下 | 复制代码 |
<?php
|
本例将输出:
<b>example: </b>, <div align=left>this is a test</div>
example: , this is a test
因此,$out[0] 包含匹配整个模式的字符串,$out[1] 包含一对 HTML 标记之间的字符串。
如果使用PREG_SET_ORDER
对结果排序使 $matches[0] 为第一组匹配项的数组,$matches[1] 为第二组匹配项的数组,以此类推。(即$matches[0] [0]为第一组匹配项中完整匹配的字符串,$matches[0] [1]为第一组匹配中完整匹配第一个括号中的字符串)
代码如下 | 复制代码 |
<?php
|
本例将输出:
<b>example: </b>, example:
<div align=left>this is a test</div>, this is a test
本例中,$matches[0] 是第一组匹配结果,$matches[0][0] 包含匹配整个模式的文本,$matches[0][1] 包含匹配第一个子模式的文本,以此类推。同样,$matches[1] 是第二组匹配结果,等等。
PREG_OFFSET_CAPTURE
如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其在 subject 中的偏移量。本标记自 PHP 4.3.0 起可用。
如果没有给出标记,则假定为 PREG_PATTERN_ORDER。
返回整个模式匹配的次数(可能为零),如果出错返回 FALSE。
例子 1. 从某文本中取得所有的电话号码
代码如下 | 复制代码 |
|
例子 2. 搜索匹配的 HTML 标记(greedy)
代码如下 | 复制代码 |
本例将输出: |
part 3: </a>
例1. 在文本中搜索“php”
代码如下 | 复制代码 |
<?php // 模式定界符后面de “i” 表示不区分大小写字母de搜索 if (preg_match (“/php/i”, “PHP is the web scripting language of choice.”)) { print “A match was found.”; } else { print “A match was not found.”; } ?> |
例2. 搜索单词“web”
代码如下 | 复制代码 |
<?php /* 模式中de b 表示单词de边界,因此只you独立de “web” 单词会被匹配, * 而不会匹配例如 “webbing” 或 “cobweb” 中de一部分 */ if (preg_match (“/bwebb/i”, “PHP is the web scripting language of choice.”)) { print “A match was found.”; } else { print “A match was not found.”; } if (preg_match (“/bwebb/i”, “PHP is the website scripting language of choice.”)) { print “A match was found.”; } else { print “A match was not found.”; } ?> |
例3. 从 URL 中取出域名
代码如下 | 复制代码 |
<?php // 从 URL 中取得主机名 preg_match(“/^(http://)?([^/]+)/i”, $host = $matches.; // 从主机名中取得后面两段 preg_match(“/[^./]+.[^./]+$/”, $host, $matches); echo “domain name is: {$matches[0]}n”; ?> 输出: domain name is: php.net |
preg_match_all 导致apache 重启的解决办法
如 preg_match_all("/ni(.*?)wo/", $html, $matches);)进行分析匹配比较长的字符串 $html 时(大于10万字节,一般用于分析采集回来的网页源码),Apache服务器会崩溃自动重启。
在Apache错误日志里有这样的提示:
[Thu Apr 11 18:31:31 2013] [notice] Parent: child process exited with status 128 -- Restarting.
[Thu Apr 11 18:31:31 2013] [notice] Apache/2.2.9 (Win32) PHP/5.2.17 configured -- resuming normal operations
[Thu Apr 11 18:31:31 2013] [notice] Server built: Jun 13 2008 04:04:59
[Thu Apr 11 18:31:31 2013] [notice] Parent: Created child process 2964
[Thu Apr 11 18:31:31 2013] [notice] Disabled use of AcceptEx() WinSock2 API
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Child process is running
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Acquired the start mutex.
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Starting 350 worker threads.
[Thu Apr 11 18:31:31 2013] [notice] Child 2964: Listening on port 80.
那么如何增加win平台下 ThreadStackSize 的大小呢? 在apache的配置文件 httpd.conf 里启用 “Include conf/extra/httpd-mpm.conf”(删除前面的注释#),然后在 httpd-mpm.conf 文件里的 mpm_winnt_module 配置模块里设置 “ThreadStackSize 8400000”即可(大约8M)。
代码如下 复制代码
代码如下 | 复制代码 |
<IfModule mpm_winnt_module> ThreadStackSize 8400000 ThreadsPerChild 200 MaxRequestsPerChild 10000 Win32DisableAcceptEx </IfModule> |
这里需要注意的是,32位的Apache程序只能最多使用大约2GB内存空间! 因此,ThreadStackSize 和ThreadsPerChild 的值相乘后(8M * 200)不应该超过2G,否则无法启动apache,出现的错误日志如下:
[Thu Apr 11 20:02:45 2013] [crit] (OS 8)存储空间不足,无法处理此命令。 : Child 4832: _beginthreadex failed. Unable to create all worker threads. Created 212 of the 220 threads requested with the ThreadsPerChild configuration directive.
通过上面的提示,飘易可以告诉大家的是在我的这台服务器上,当线程堆栈大小设为8M时,我可以设置的线程数最多是212个。
一般情况下,PHP都是将整个页面全部执行完成后,才会把要输出的内容发送回客户端。例如有如下代码:
代码如下 | 复制代码 |
for ($i = 0; $i < 10; $i++) { |
这段代码会在10秒钟后一次性输出“0123456789”。
对于运行时间较长的PHP程序来说可能都需要即时输出内容来查看运行情况。
代码如下 | 复制代码 |
header(“Content-type:text/html;charset=utf-8″); |
#设置执行时间不限时
代码如下 | 复制代码 |
set_time_limit(0); |
#清除并关闭缓冲,输出到浏览器之前使用这个函数。
代码如下 | 复制代码 |
ob_end_clean(); |
#控制隐式缓冲泻出,默认off,打开时,对每个 print/echo 或者输出命令的结果都发送到浏览器。
代码如下 | 复制代码 |
ob_implicit_flush(1); |
这就用到了PHP的输出控制函数ob_flush()和flush()。我们把代码修改成下面这样:
代码如下 | 复制代码 |
|
这段代码则会马上在屏幕上打印 Hello world。关键就在于第2和第3行调用的两个函数 ob_flush() 和 flush()。这两个函数得一起使用才能保证页面马上输出Hello world。其中str_repeat(' ', 256)则是为了解决某些浏览器必须在接收到256个字符后才会显示内容。
对上面函数升级
代码如下 | 复制代码 |
$buffer = ini_get('output_buffering'); for($i=1;$i<100;$i++){ |
这样,页面就会每一秒输出一个数字。
我们可以很方便的使用PHP的输出控制来实现页面执行进度的显示。不过,由于PHP页面有执行时间限制,而且长时间执行一个页面会对服务器造成一定的压力
代码
代码如下 | 复制代码 |
header("Cache-Control:no-cache,must-revalidate,no-store"); //这个no-store加了之后,Firefox下有效 |
这个页面不缓存了,并且有个判断购物车商品为空就跳转到空购物车的页面,那么用户点击浏览器后退,回来之后,也直接到 购物车页面了。
PHP 禁止浏览器缓存页
代码如下 | 复制代码 |
<?php |
但加上面三句在IE中有效,在FF中无效,在FF中在加上下面这句。
代码如下 | 复制代码 |
<meta http-equiv="Cache-Control" content="no-store"> |
日我突发奇想,找到了一种在任何情况下都会显示最新的网页内容的方法,描述如下:
请将网页的链接改为:
http://xxx.yyy.zzz/page.php?rand=XXXXXXX
其中http://xxx.yyy.zzz/page.php是你的网页,rand是一个你不会用到的Qurey字串,XXXXXXX是一个随机字串。
其它的如asp,jsp设置方法
ASP:
代码如下 | 复制代码 |
response.expires=0 |
JSP:
代码如下 | 复制代码 |
response.setHeader("Pragma","No-cache"); |
排序实现过程如下:
49 38 65 97 76 13 27
38 49 65 97 76 13 27 比较第1个和第2个数,小的放前边,大的放后边 38 49 65 97 76 13 27 比较第2个和第3个数,小的放前边,大的放后边 38 49 65 97 76 13 27 比较第3个和第4个数,小的放前边,大的放后边 38 49 65 76 97 13 27 比较第4个和第5个数,小的放前边,大的放后边 38 49 65 76 13 97 27 比较第5个和第6个数,小的放前边,大的放后边 38 49 65 76 13 27 97 比较第6个和第7个数,小的放前边,大的放后边 至此,第一趟比较结束,得到以下排序: 38 49 65 76 13 27 97
然后按照第一趟排序的方法继续比较,直到完成排序。
列1
代码如下 | 复制代码 |
$arr = array(345,4,17,6,52,16,58,69,32,8,234); |
列2
代码如下 | 复制代码 |
/** $arr = array(56,2,5,78,110,36,52,77,89,3,10); |
我们先来看我实现无限分类的具体过程。
题设:类似淘宝的商品分类,可以在任意分类设置其子类。
一、创建`type`数据表
代码如下 | 复制代码 |
`id` 自增长 `fid` int(11) 默认(0) ,父节点id `name` varchar(50),分类名称 CREATE TABLE `type` ( |
二、添加
我们先添加几个顶级分类
代码如下 | 复制代码 |
INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '0', '手机'); |
接着我们为{电脑}添加几个个子分类
代码如下 | 复制代码 |
INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '2', '台式'), (NULL, '2', '笔记本');这里fid=2, |
2这个id是分类{电脑}的id,如果是添加{鞋子}的子分类则fid=3
同理我们为{笔记本}添加子分类则fid=6
代码如下 | 复制代码 |
INSERT INTO `type` (`id`, `fid`, `name`) VALUES (NULL, '6', 'ausu'), (NULL, '6', 'hp'); |
三、删除
如果我们想删除{笔记本}这个分类,很简单
DELETE FROM `type` WHERE `id`=6{笔记本}的子分类我们也要记得做相应的处理
代码如下 | 复制代码 |
|
del(6);//执行操作这里你也许你会疑惑为什么那么麻烦用递归,而不是直接这样删除
DELETE FROM `type` WHERE `fid`=6这样我们不就可以直接删除{ausu}、{hp}?但是假设{ausu}有一个子分类{a1},{a1}也有一个子分类{a2},如果不用递归我们就无法彻底删除数据。
三、查找
1.查找{电脑}的子分类
SELECT * FROM `type` WHERE `fid`=22.查找{电脑}的所有子分类
代码如下 | 复制代码 |
sel(2); |
四、实际数据应用
在数据表添加一个字段`tid`,字段值为记录所属分类`type`表的id。必须是id不能是name,因为name的值可能会改变。
例如查询属于{电脑}分类的商品
代码如下 | 复制代码 |
SELECT * FROM `goods` WHERE `tid`=2 |
下面再看个实例,直接操作数组
代码如下 | 复制代码 |
<?php // 72648 function findChild(&$arr,$id){ echo memory_get_usage(); print_r($tree);
|
我自己用的可以做那种下拉效果并带有级数的效果
代码如下 | 复制代码 |
dafenglei_select(0,0, $fenlei ); |
$fenlei 无限分类数组 $id是选择从哪个分类开始 写0代表顶级开始分,只要把数组放进去就可以分了