PHP不支持多线程编程,于是,当需要同时执行多个任务的时候,就有些力不从心了;对于有些任务可以通过异步的方式来处理,如: 同时执行多个http请求;对于有些计算型的需求,或者是异步实现很麻烦的时候就不好办了。
当我再一次看fork/exec/system/source等类似的命令或系统调用的时候,觉得他们和之间的异同比较有意思,比如:
fork: 创建子进程,当前进程继续运行
exec: 当前进程直接让位于要执行的程序,用不返回
system: 使用当前进程的环境,创建一个子进程,等待子进程执行完成后返回; system=fork+exec+waitpid

于是想到了PHP中的popen,该方法可以和执行一个外部命令,但是不阻塞当前进程,只需要使用循环去收集执行结果就行了。

对于web程序,通过异步的http请求将任务提交给本机的web server或许比popen更加合算一些。
by phpor | 不指定 2012/05/19 22:43 | 数据存储 » PHP | 评论(0) | 引用(0) | 阅读(48)
首先,我编译PHP时使用如下命令:
./configure --prefix=/usr/local/php-5.3.3 && make

完成之后,发现默认的php.ini 为: /usr/local/php-5.3.3/lib/php.ini ; 于是我改变了注意,想修改prefix为 /usr/local , 如果不执行make clean的话,则
./configure --prefix=/usr/local && make

发现默认的php.ini 仍为: /usr/local/php-5.3.3/lib/php.ini

看来必须make clean了, 似乎configure之后生成的头文件: ./main/build-defs.h 是不被依赖的
by phpor | 不指定 2012/04/26 15:04 | 数据存储 » PHP | 评论(0) | 引用(0) | 阅读(3141)

测试脚本a.php:
  1. <?php
  2. include_once("b.php");
  3. echo "=====\n";
  4. include_once("b.php");
  5. echo "=====\n";
  6. include_once("c.php");

目录结构:
a.php
b.php

include_path 的 = .;/usr/local/lib/php

strace -e file php a.php
------------------------------
open("a.php", O_RDONLY)                 = 3     // 打开a.php
getcwd("/usr/home/junjie2", 4096)       = 18
lstat64("/usr/home/junjie2/a.php", {st_mode=S_IFREG|0644, st_size=108, ...}) = 0
lstat64("/usr/home/junjie2", {st_mode=S_IFDIR|0777, st_size=36864, ...}) = 0
lstat64("/usr/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
getcwd("/usr/home/junjie2", 4096)       = 18     // get current working directory (这个就是include_path 中的 "." )
lstat64("/usr/home/junjie2/./b.php", {st_mode=S_IFREG|0644, st_size=7, ...}) = 0   // 找见了
lstat64("/usr/home/junjie2/b.php", {st_mode=S_IFREG|0644, st_size=7, ...}) = 0
open("/usr/home/junjie2/b.php", O_RDONLY) = 3
=====
getcwd("/usr/home/junjie2", 4096)       = 18  // 这次包含没有真实的文件操作,因为包含过了的文件PHP自己都知道,可以使用get_included_files()来查看,所以就不需要再lstats和open了
=====
getcwd("/usr/home/junjie2", 4096)       = 18      // get current working directory (这个就是include_path 中的 "." )
lstat64("/usr/home/junjie2/./c.php", 0xbf904350) = -1 ENOENT (No such file or directory)  // 没找见
lstat64("/usr/local/lib/php/c.php", 0xbf904350) = -1 ENOENT (No such file or directory)     // 去include_path 中的 "/usr/local/lib/php" 下面找还没找见
lstat64("/usr/home/junjie2/c.php", 0xbf904350) = -1 ENOENT (No such file or directory)    // 去脚本所在的目录下面找此次查找和include_path 无关
getcwd("/usr/home/junjie2", 4096)       = 18  // 这里又查一次,why?
lstat64("/usr/home/junjie2/./c.php", 0xbf9042a0) = -1 ENOENT (No such file or directory)
lstat64("/usr/local/lib/php/c.php", 0xbf9042a0) = -1 ENOENT (No such file or directory)
lstat64("/usr/home/junjie2/c.php", 0xbf9042a0) = -1 ENOENT (No such file or directory)
getcwd("/usr/home/junjie2", 4096)       = 18
lstat64("/usr/home/junjie2/c.php", 0xbf906390) = -1 ENOENT (No such file or directory) // 这次查找可能是报错的时候查的
open("/usr/home/junjie2/c.php", O_RDONLY) = -1 ENOENT (No such file or directory)


结论:
1. 先查找 include_path 设置的目录; 其中的 "." 代表的不是脚本所在目录,而是脚本运行时的cwd(当前工作目录),这个目录是可以通过chdir修改的
2. 如果include_path 中查不到,则再查找脚本所在目录,这个和是否设置了include_path 无关
3. ini_set("include_path", ""); 第二个参数不能为空,为空的话就没有任何作用
by phpor | 不指定 2012/04/17 20:08 | 数据存储 » PHP | 评论(0) | 引用(0) | 阅读(3574)
关于PHP的一个小题目:
 
  1. <?php
  2. $arr = array(1,2,3);
  3. foreach($arr as $num) { 
  4.     if ($num == 2) $arr[] = 4;
  5.     echo $num;
  6. }
输出结果: 1234 还是 123 ?
答案: 123

如果才能达到 1234 的效果呢?

使用list、each, 代码如下:
 
  1. <?php
  2. $arr = array(1,0,null,2,3);
  3. while(list($key$num) = each($arr)) {
  4.     if ($num == 2) $arr[] = 4;
  5.     echo $num;
  6. }

  7.     


by phpor | 不指定 2012/04/16 16:42 | 数据存储 » PHP | 评论(0) | 引用(0) | 阅读(2685)

bug描述: http://www.laruence.com/2011/12/29/2412.html
相关资料: http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html

就像上面资料中提到的,构造hash冲突是利用了PHP Hashtable对数值key的简单处理实现的。如果用字符串key来构造hash冲突,似乎就比较麻烦了; 严格地将,这个和PHP中的hash算法没有必然联系,对于字符串key是通过hash函数计算出一个无符号整型数然后和Hashtable的size取模的,而对于数字key是直接使用该数字与Hashtable的size取模的。

有些同学通过限制post数据的大小来从一定程度上环节带来的危害,限制post数据大小为不超过100k,下面来分析一下这个数字是否够用:
脚本1:
 
  1. <?php
  2. $size = pow(2, 15); // 可以通过第二个参数来改变提交的数据量的大小
  3. $data = '';
  4. for ($key=0, $maxkey=($size-1) * $size$key<= $maxkey$key+=$size) {
  5. $data .= $key.'=&';
  6.     $i++;
  7. }
  8. echo "key num: $i \n";
  9. echo "data length:"strlen($data);
通过这个脚本来得出key的多少和对应的数据量。

脚本2:
 
  1. <?php
  2. $size = pow(2, 15); // 16 is just an example, could also be 15 or 17
  3. $startTime = microtime(true);
  4. $array = array();
  5. for ($key = 0, $maxKey = ($size - 1) * $size$key <= $maxKey$key += $size) {
  6.         $array[$key] = 0;
  7. }
  8. $endTime = microtime(true);
  9. echo 'Inserting '$size' evil elements took '$endTime - $startTime' seconds'"\n";
  10. $startTime = microtime(true);
  11. $array = array();
  12. for ($key = 0, $maxKey = $size - 1; $key <= $maxKey; ++$key) {
  13.         $array[$key] = 0;
  14. }
  15. $endTime = microtime(true);
  16. echo 'Inserting '$size' good elements took '$endTime - $startTime' seconds'"\n";
通过这个脚本可以得出key的多少和相应消耗的时间。

80k的数据就可以构造8000 个key,耗费cpu时间大约不到2s;

360k的数据可以构造3.2万个key,耗费cpu时间大约30多s;

 

看来限制 100k 的数据还是非常有效的。

关于该bug的修复,官方给出了补丁,允许限制post数据的个数; 那么GET数据和Cookie数据会不会有这个问题呢?答案是不会的,我们可以从apache的源码中找到答案:



关于PHP Hashtable的更多参考资料:
http://www.qingliangcn.com/2009/07/php%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8Bhashtable/
http://www.phpchina.com/index.php?action-viewthread-tid-88505

---------------------
关于PHP Hashtable的几点提示:
1. Hashtable的最小大小为8 ,如果元素个数为9,则大小重新调整为16,每次调整都要遍历所有元素,重新计算hash值
2. 数值key不做hash,直接和Hashtable 的size取模
3. nNextFreeElement 用于数字索引的计数,其值为当前数字索引值加1,初始值为0
4. pNext, pLast 是hash冲突时的冲突链表的双向指针
5. PListNext, pListLast 是用于遍历数组的双向链表指针
6. pInternalPointer  是用于遍历数组的一个位置指针



by phpor | 不指定 2012/01/02 02:16 | 数据存储 » PHP | 评论(0) | 引用(0) | 阅读(3303)
分页: 1/26 第一页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]