背景:有时候用户输入了email,xxx@xxxxx.com,这个xxxxx.com是否真有A记录,MX 记录也就是说是否真有这个邮件提供商,怎么用PHP函数知道呢?checkdnsrr函数就知道,如下两种用法:
一、php验证用户输入的邮箱有效性和正确性,用checkdnsrr验证email的域名部分的有效性:

注意:checkdnsrr函数在win主机上是无效的!下面是国外某程序员提出的一种解决办法,另外写了个函数代替checkdnsrr函数:

摘自:http://www.educity.cn/develop/406028.html
二、checkdnsrr -- 根据一个给定的host name(域名)或者IP地址检查它是否有DNS记录,其实也就是检验它是否存在。
checkdnsrr — Check DNS records corresponding to a given Internet host name or IP address
译文: checkdnsrr -- 根据一个给定的host name(域名)或者IP地址检查它是否有DNS记录,其实也就是检验它是否存在。
Note:  This function is now available on Windows platforms.
注意:该函数在windows平台不支持
我试了一下,果然,提示没有这个函数。
下面是一个hack的方法,这样,我们在windows上做开发时,也能看到效果了!

接下来我来介绍一下参数:
    bool checkdnsrr ( string $host [, string $type = "MX" ] )
    第一个参数我们就不说了,就是域名或者ip
    第二个参数是解析类型,分别有:
    A (Address) 记录     是指定主机名(或域名)对应的IP地址记录。
    MX 记录              是指定邮件交换记录(默认)
    NS 记录              是指定域名服务器的记录,指定该域名由哪个DNS来进行解析。
    SOA记录              一般在辅助的dns服务器里才用到,用来指定谁是主服务器。
    PTR记录              从ip指向域名的反向解析记录
    CNAME记录            别名记录
    AAAA记录             是一个指向IPv6的记录
    A6记录               同上
    SRV记录              它是DNS服务器的数据库中支持的一种资源记录的类型,一般是为Microsoft的活动目录设置时的应用。
    TXT记录              文本信息
    ANY记录              任何记录,所有数据类型
这个函数常被我们用于检测email是否真实存在!
摘自:http://blog.sina.com.cn/s/blog_4ce89f200100uk74.html
阅读全文
背景:安装一个破解版的Zend Studio 12.0.1后,发现PHP内置函数出现警告,按http://www.geekso.com/ZendStudioCodeAutocomplete/ 处理后也不行,于是:
**
在用 Zend Studio 编写 PHP 项目时发现调用系统函数时调试正常, 但是在编写代码时却提示函数未定义"Call to undefined function ", 在左侧语法检测状态区域栏总是显示个小黄色的三角形的感叹号. **'

解决办法:

1, 修改项目 .buildpath 文件

<?xml version="1.0" encoding="UTF-8"?> <buildpath> <buildpathentry kind="src" path=""/> <buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/># 新增一句 kind="con" </buildpath>

2, 重置项目编译状态

Project -> Clean -> Clean all projects

3, 重新编译项目

Project -> Build All

4, 完成! 再看看是不是小黄色的感冒号图标消失啦~

提醒: PHP Language Library 中存放的都是一些系统函数以及扩展库函数的定义原型, 当编码时调用这些函数时 Zend Studio 可以根据这些定义原型进行代码提示及补全.

最后,通过 zend studio 菜单 帮助 >> welcome 安装高版本的PHP, 可以得到支持.
Zend Studio 12.0.1默认是没有一个PHP版本的,得添加后才能支持到PHP内置函数不警告。

实践上都没有搞定:什么把PHP各个版本给加在welcome页面上选上apply啊,我把原来的样式和workspace-》defaultworkspace给删除干净后,重新指向这个地方,导入:Zend Studio 10.5.0 首选项配置文件-2014-01-07.epf 后,把前面的项目给重新建立项目,于是不警告了,好了。
参考:
http://segmentfault.com/blog/fengxiuping/1190000000449206
http://bbs.itcast.cn/thread-7244-1-1.html
背景:i++还是++i这个问题,我为什么记下了,又忘记了,我觉得这是一个哲学问题。
这是一个医学问题,这是一个物理问题:

Firefox下,打开一个空白页面,按下:Shift+F4,调出Js调试工具:


先后是:
1
2
2
2
原因如下:
a= i++;
则相当于  a=i;i=i+1;   //alert i++ 时:相当于a=i,还是原值1。后面再alerti时相当于i=i+1了等于2.
a=++i;
则相当于  i=i+1;a=i;// alert ++i 时,相当于前面的i=i+1,所以就等于2了,而接着再alert i 时还是2.
________________________________________________________
都是i=i+1的意思,区别在于i++是i先不自加,在语句完后自加,++i先自加;
列如a=1+i++;i本来为1的话,这里a=1+1;语句完后i才加1为2;
a=1+++i的话就先i=i+1;i=2.然后a=i+1,a=3

直接使用看不出区别,都是变量i加1
在赋值时才能进行区别,
如:
y=i++  // y的值为i (先引用,后运算)
y=++i  // y的值为i+1的结果 (先运算,后引用)

++i是在使用i之前先使i的值加1
i++是在使用i之后,使i的值加1
背景:用PHP做一些简单的上传是没有任何的问题,但是要做断点上传好像也是没有大问题,但要是并发的切片加断点上传可能就会有问题了哟。
第一个问题是合并问题:如果一上传就合并,PHP老半天不返回是一个方面(是PHP超时还是Nginx超时?),这样势必会造成客户端因没返回,没法再启动新的上传进程,如果用php的追加写文件内存太大还会退出的可能,用上gearmand后出现异步同时写,可能加快了传输效率的同时IO可能会比较密集(假如同一时间并发上传的人多的情况。)。
第二个问题是先后问题:如果并发时出现了传一半时最后一片先上传上来了怎么办?如果直接追加进文件是会不按顺序出错的,如果放在那儿不管,那啥时候管,这也是一个问题。
第三个问题是锁的问题:并发时如果同时两片到了,像PHP这种如何去结合锁的功能呢?据我所知有memcache的add函数是原子操作,可以利用,那就设计到锁多久,是不是又回到第一个问题,返回时间得浪费多长时间呢。
基于上面三点,看来PHP做这活不是太靠谱,于是引出了gearman这个模型,相当于异步处理,再集合PHP的memcache锁(memcache放内存,可能得用ttserver才行,协议一样的。),PHP上传逻辑处理,Nginx上传插件,才有可能做一个较为靠谱且稳定的分片,断点加多进程(多线程)上传服务搭建。

一、从源码安装gearmand遇到的各种外部代码版本及yum版本太低的导致各种编译不过的问题,历程相当的麻烦,特别是boost和这个libevent默认的yum install非常低,都给编译了,把rpm所强制删除了,最后才成功,再就是g++编译版本,得export后才能编译,否则一堆问题,都在下面有描写。
出现第一个问题及处理办法:
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'bool gearmand::queue::Instance::_sqlite_prepare(const std::string&, sqlite3_stmt**)':
libgearman-server/plugins/queue/sqlite/instance.cc:125: error: 'sqlite3_prepare_v2' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'gearmand_error_t gearmand::queue::Instance::init()':
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_READWRITE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_CREATE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'sqlite3_open_v2' was not declared in this scope
make[1]: *** [libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo] Error 1
将队列存放在sqlite3或postgresql。这货是用的sqlite存队列啊:
yum search sqlite
yum install sqlite.x86_64 sqlite-devel.x86_64
还是不行,参考:
安装:https://jackxiang.com/post/7709/ 后,
最后在编译Gearman时带上 --with-sqlite3=/usr/local/sqlite3,告诉编译器应该使用这个新的sqlite即可。


出现第二个问题及处理办法:
./libgearman-1.0/gearman.h:53:23: error: cinttypes: No such file or directory
命令:
yum install gcc44 gcc44-c++ libstdc++44-devel -y
然后在环境变量里加入:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc
export CXX=/usr/bin/g++44
保存退出后执行:
source /etc/profile
删除gearmand-0.34文件夹重新进行编译.
重新进行编译后执行make这步......

看来还得重新export一次新的编译器,因为昨天的关了终端,今天的又没了:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc  //这行有问题~
export CXX=/usr/bin/g++44
g++ -o testmemcached testmemcached.cpp -lmemcached
为何还是不行?
echo $CC
/usr/bin/gcc  //没变,这儿有问题,再重新设置一次,查到上面这个or有问题:export CC=/usr/bin/gcc44。
# echo $CXX
/usr/bin/g++44 //变了

重新设置,好了:
export CC=/usr/bin/gcc44
/usr/bin/gcc44

在后面有详细的说明,可以不source直接设置环境变量,因为编译后也不一定要这个版本的gcc的。



出现第三个问题的处理办法:
ibgearman-server/plugins/queue/mysql/queue.cc:430: error: 'mysql_error' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc: In function 'gearmand_error_t _mysql_queue_replay(gearman_server_st*, void*, gearmand_error_t (*)(gearman_server_st*, void*, const char*, size_t, const char*, size_t, const void*, size_t, gearman_job_priority_t, int64_t), void*)':
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'MYSQL_RES' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'result' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:447: error: 'MYSQL_ROW' was not declared in this scope

[root@test gearmand-1.1.12]# ./configure --help|grep mysql
  --with-mysql=[ARG]      use MySQL client library [default=yes], optionally
                          specify path to mysql_config
              Full path to mysql_config program

看样子是想用mysql做队列queue的:


加上还是报错,去了得了,不用mysql做队列,有sqlite足够了,
--without-mysql就好了,来自:
https://bugs.launchpad.net/gearmand/+bug/1327038 说的:


出现第四个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::m_default_line_length'
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::options_description(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::run()':
/usr/local/include/boost/program_options/detail/parsers.hpp:107: undefined reference to `boost::program_options::detail::cmdline::get_canonical_option_prefix()'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::extra_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)':
/usr/local/include/boost/program_options/detail/parsers.hpp:77: undefined reference to `boost::program_options::detail::cmdline::set_additional_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)'
collect2: ld returned 1 exit status
make[1]: *** [bin/gearadmin] Error 1
make[1]: Leaving directory `/home/xiangdong/software/gearmand-1.1.12'


[root@test gearmand-1.1.12]# ./configure --help|grep boost
  --with-boost[=ARG]      use Boost library from a standard location
  --with-boost-libdir=LIB_DIR
                          Force given directory for boost libraries. Note that
                          fails and you know exactly where your boost
  --with-boost-program-options[=special-lib]
                          use the program options library from boost - it is
                          --with-boost-program-options=boost_program_options-gcc-mt-1_33_1

指定boost的库:
从这儿得知在这儿呢:  http://jackxiang.com/post/7706/
系统默认会将include拷贝到/usr/local/include/boost/中
将lib拷贝到/usr/local/lib下
yum install boost-devel  [实践失败]
回头了解下boost的结构,rpm包是啥样的,如下所示,版本号1.33,有可能是因为lddconfig里默认配置指向这个旧版本了,如下:
vi /etc/ld.so.conf


[root@test ~]# rpm -ql boost-1.33.1-16.el5_9
/usr/lib64/*.so.*  //各种so文件
/usr/lib/*.so.*     //各种so文件
rpm -ql boost-devel-1.33.1-16.el5_9
/usr/include/boost  里面是各种分类目录,里面是hpp头文件
algorithm/
archive/
assign/
bind/
compatibility
config/
devel包里还有静态a文件及动态so文件:
/usr/lib/libboost_test_exec_monitor.a
/usr/lib/libboost_test_exec_monitor.so

如下实践试试:
cd /home/xiangdong/software/boost_1_57_0
./bootstrap.sh --prefix=/usr/local/boost-1.57
vi tools/build/v2/user-config.jam
文件尾部增加(没找到,直接./b2 ./b2 install 即可!):
using mpi  
./b2
./b2 install


Boost headers version >= 1.39.0
[root@localdomain gearmand-1.1.12]# yum search boost
[root@localdomain gearmand-1.1.12]# yum install boost.x86_64
[root@localdomain gearmand-1.1.12]# yum install yum install boost-devel.x86_64
旧的yum源,直接干死,用源码装个试试:



出现第五个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/libgearman-server/gearmand_con.cc:677: undefined reference to `event_initialized'
collect2: ld returned 1 exit status
libevent版本太老了,更新新的版本:
安装最新版本的libevent,并执行以下操作:(备份老版本的/usr/lib64/libevent.so)
ln -s /usr/lib64/libevent-2.0.so.5 /usr/lib64/libevent.so
删除老旧的libevent的rpm包后,安装最新的方法实践如下:
[root@test software]# cp  /usr/lib64/libevent.so /usr/lib64/libevent.so.bak.old
[root@test libevent-2.0.21-stable]# tar -zxvf libevent-2.0.21-stable.tar.gz
[root@test libevent-2.0.21-stable]# cd libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr/local/libevent-2.0.21-stable


ls -al /usr/lib | grep libevent
rpm -qa|grep libevent
libevent-1.4.13-1
libevent-devel-1.4.13-1
libevent-devel-1.4.13-1
libevent-1.4.13-1

rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]# rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]#

卸载后看还有没:
[root@test libevent-2.0.21-stable]# ls -al /usr/lib | grep libevent  
lrwxrwxrwx   1 root root       31 Dec 30 17:17 libevent-1.1a.so.1 -> /usr/lib/libevent-1.1a.so.1.0.2
-rw-r--r--   1 root root    31596 Jan  7  2007 libevent-1.1a.so.1.0.2

rm -Rf  /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1 //删除干净
[root@test libevent-2.0.21-stable]# rm -Rf  /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1
[root@test libevent-2.0.21-stable]#

cd /home/xiangdong/software/libevent-2.0.21-stable  //最新安装包
./configure --prefix=/usr   //libevent会安装到 /usr/lib 或 /usr/local/lib 下
#./configure --prefix=/usr/local/libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr && make && make install
测试libevent是否安装成功:ls -al /usr/lib | grep libevent(或 ls -al /usr/local/lib | grep libevent)
ls -al /usr/lib | grep libevent
lrwxrwxrwx   1 root root       21 Dec 31 09:44 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9
-rwxr-xr-x   1 root root  1065819 Dec 31 09:44 libevent-2.0.so.5.1.9
-rw-r--r--   1 root root  1678970 Dec 31 09:44 libevent.a
lrwxrwxrwx   1 root root       26 Dec 31 09:44 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.1.9

如果libevent的安装目录为/usr/local/lib下,则还需要建立 libevent-1.4.so.2 到 /usr/lib 的软连接,这样其他程序运行时才能找到libevent库:ln -s /usr/local/lib/libevent-1.4.so.2  /usr/lib/libevent-1.4.so.2

ls /usr/lib/libevent-2.0.so.5
/usr/lib/libevent-2.0.so.5

干掉旧的libevent的残留的动态so文件:
ls -al /usr/lib64 | grep libevent
lrwxrwxrwx   1 root root       19 Dec 31 09:40 libevent-1.4.so.2 -> libevent.so.bak.old
-rwxr-xr-x   1 root root   104296 Dec 31 09:22 libevent.so.bak.old
[root@test libevent-2.0.21-stable]# rm -Rf /usr/lib64/libevent-1.4.so.2
参考来自:http://blog.sina.com.cn/s/blog_4b93170a0100mbm9.html

编译成功结果如下:


启动gearmand的方法:
[root@test gearmand-1.1.12]# whereis gearmand
gearmand: /usr/local/sbin/gearmand
[root@test ~]# mkdir -p /usr/local/gearman/log

ls /usr/local/sqlite3/bin/
sqlite3

*特别提醒,(mysql性能上可能在做队列上并不比sqlite强到哪儿去)
使用sqlite更加简单方便 :
/usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
很遗憾,我到现在也没能编译出对MySQL的持久化

[root@test ~]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
/usr/local/sbin/gearmand: Error while initializing the queue : libsqlite3

原来是sqlite的位置不对,修改路径后就OK了:

启动成功:
[root@test sqlite3]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite3/bin/gearman --libsqlite3-table gearman_queue -d
[root@test sqlite3]#
端口存在了,说明是真的启动成功了:
[root@test sqlite3]# netstat -atlunp|grep 4830
tcp        0      0 0.0.0.0:4830                0.0.0.0:*                   LISTEN      17820/gearmand      
tcp        0      0 :::4830                     :::*                        LISTEN      17820/gearmand  

也就是说gearmand启动时候自己建立一个sqlite的表,如下:
[root@test sqlite3]# cat /usr/local/sqlite3/bin/gearman
SQLite format 3@  ''blegearman_queuegearman_queueCREATE TABLE gearman_queue ( unique_key TEXT, function_name TEXT, priority INTEGER, data BLOB, when_to_run INTEGER, PRIMARY KEY (unique_key, function_name))9M'indexsqlite_autoindex_gearman_queue_1gearman_queue

经过一陈折腾,说明这个gearmand对boost库的要求高,对libevent的版本也要求高,不是能经过yum install能解决得了的,得自己安装后指定,再就是对编译器的版本也是有要求的,也就是说相对来说其安装比较苛刻一些,如Lamp架构相比较的话,难度要高一些。
——————————————————————————————————————————————————————————————
总之,一大堆问题,这货居然还这么流行听说Gearman最初用于LiveJournal的图片resize功能,由于图片resize需要消耗大量计算资 源,因此需要调度到后端多台服务器执行,完成任务之后返回前端再呈现到界面。,看来广大分发系统还真得靠它啊,其它各种小问题不断,参考:
http://www.111cn.net/sys/CentOS/65334.htm

二、PHP的gearmand扩展编译及遇到问题解决实践如下:
PHP的gearmand折腾扩展,这块试了好几个版本的扩展要么configure不过去,要么是lib里却啥,但最后还是以当前最新的版本gearman-1.1.2.tgz给解决了:

./configure --with-php-config=/usr/local/php/bin/php-config
出现如下所示的配置错误:
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
checking for gawk... gawk
checking whether to enable gearman support... yes, shared
found in /usr/local
checking for gearman_create in -lgearman... no
configure: error: wrong libgearman version or lib not found

问题一:
gearman的PHP扩展时出现configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.警告信息。
警告信息说明需要安装 re2c
执行下面命令安装:
wget http://sourceforge.net/projects/re2c/files/re2c/0.13.5/re2c-0.13.5.tar.gz/download
2014-12-31 11:01:59 (999 KB/s) - `re2c-0.13.5.tar.gz' saved [782725/782725]
tar -zxvf re2c-0.13.5.tar.gz
cd re2c-0.13.5
./configure && make && make install //安装成功,警告得到了解决,第二个依旧存在。
它的意思是好像没有找到lib,不对是找到了没有找到里面的某个叫gearman_create的函数,这个就奇怪了,找下:
[root@test /]# find . -name "*gearman*.so*"
./usr/local/lib/libgearman.so.8.0.0
./usr/local/lib/libgearman.so
./usr/local/lib/libgearman.so.8

[root@test /]# vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/lib
/lib64
/usr/lib                                                                                                                                                                                            
/usr/lib64
/usr/local/lib
/usr/local/lib
有这个位置的啊。
[root@test /]# ldconfig  //重新lib的位置载入。

[root@test gearman-0.4.0]# phpize
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626
[root@test gearman-0.4.0]# ./configure --with-php-config=/usr/local/php/bin/php-config

问题依旧,去官网看一下呗,http://gearman.org/download/:
文字摘录:PHP
There are two PHP client/worker libraries, one which is a pure PHP extension and one which wraps the libgearman C library.
Gearman Extension
A PHP extension that wraps the libgearman C library.
Gearman PHP Extension (1.0.2) (Source)
官方的PHP扩展高V1.0.2,我这个是gearman-0.4.0太旧了,好像还有更高的gearman-1.1.2.tgz,http://pecl.php.net/package/gearman,放上官网这个上去重新试下了:
tar -zxvf gearman-1.0.2.tgz
cd gearman-1.0.2
[root@test gearman-1.0.2]# phpize
./configure --with-php-config=/usr/local/php/bin/php-config   //这个没有问题
[root@test gearman-1.0.2]# make && make install
/home/xiangdong/software/gearman-1.0.2/php_gearman.c: In function ‘zm_startup_gearman’:
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: ‘GEARMAN_MAGIC_TEXT’ undeclared (first use in this function)
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: (Each undeclared identifier is reported only once
还是差啥么子玩意,换个更新的看下,gearman-1.1.2.tgz 实践OK了,如下:
Libraries have been installed in:
   /home/xiangdong/software/gearman-1.1.2/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

[root@test gearman-1.1.2]# make install
Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
真在的:
ls  /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
在php.ini里加上这个扩展就成了。Successful....EOF


[root@test gearman-1.1.2]# php -v
PHP 5.3.10 (cli) (built: Feb  3 2012 14:04:56)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator

[root@test gearman-1.1.2]# vi /usr/local/php/etc/php.ini
extension = "gearman.so"  

[root@test gearman-1.1.2]# php -m|grep gearman
gearman



三、代码编写task的分发及client的及简单代码实践OK及其情况实践Ok:
cd /usr/local/gearman/
[root@test gearman]# mkdir codesTest
[root@test gearman]# cd codesTest/
[root@test codesTest]# vi myworker.php


以守护进程方式启动worker:
# nohup php myworker.php >/dev/null 2>&1 &
[root@test codesTest]# nohup php myworker.php >/dev/null 2>&1 &
[1] 31238

一个发送任务处理请求的client:
vi  myclient.php
[root@test codesTest]# vi  myclient.php


运行myclient.php:
[root@test codesTest]# php myclient.php "Jose"
hello, Jose
H:test.local:2

一个发出并行处理任务请求的例子tasksclient:
[root@test codesTest]# vi  tasksclient.php


运行tasksclient:
[root@test codesTest]# php tasksclient.php
Completed task:: id :2 , handled result:hello, John
Completed task:: id :1 , handled result:hello, Jose

查看worker及队列情况:
(echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]#  (echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
34 192.168.109.8 - : sayhello logMsg
35 192.168.109.8 - :
.
查看当前队列情况(显示格式FUNCTION\tTOTAL\tRUNNING\tAVAILABLE_WORKERS):
(echo "status"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]# (echo "status"; sleep 0.1) | nc 192.168.109.8 4830
sayhello        0       0       1
logMsg  0       0       1
.

监控php的守护进程(没实践), 可以开多个,并同时监控:
关于Worker守护进程的启动和监控
上面例子中直接启动worker脚本作为守护进程,无法监控到worker进程是否存活.
使用Unix进程监控supervisord则可轻松解决这个问题.
将如下配置添加到supervisord的配置中,即可实现由supervisord来启动和监控myworker.
编辑配置文件 vi /etc/supervisord.conf
[program:myworker]
command=/usr/local/php5415/bin/php myworker.php
process_name=%(program_name)s_%(process_num)02d
;修改numprocs即可同时开启多个worker进程
numprocs=1
directory=/usr/local/gearman/codesTest
autostart=true
autorestart=true
user=gearmand
stopsignal=KILL
Posted in Daemon / Worker, Gearman.
Tagged gearman.

监控这块看:
http://jingyan.baidu.com/article/375c8e198d1b1425f2a2290c.html

上面这块的PHP扩展代码及实践来自:
http://www.51itstudy.com/30114.html
http://codego.net/384693/

_________下面是摘录别的文章不一定自己配置时可完全过得过,得按自己环境作配置安装,只是用作参考!_______
Gearman的目的在于用PHP扩展分发,于是PHP扩展如何安装:
tar zxvf gearman-1.1.1.tgz
cd gearman-1.1.1
/opt/local/php/bin/phpize
./configure --with-php-config=/opt/local/php/bin/php-config --with-gearman
make
make install
编辑 php.ini
vi php.ini
增加
extension = "gearman.so"
重启php

启动gearmand 服务
gearmand -L 10.6.0.6 -p 4730  -u root -l /var/log/gearmand.log -d
其他参数请  gearmand --help

摘自:http://jicki.blog.51cto.com/1323993/1177487
阅读全文
背景:用Nginx上传插件实现大文件分片上传后,处理子程序的程序需要每次对分片进行合并,但又不想耗费PHP太多内存,只好让shell来干这事儿,同时呢,又不想让PHP用exec合并文件时出现等待,怎么办?

   在php中,如果出现exec();那么php是先运行完exec中的外部命令,然后继续执行接下来的php语句的。有什么办法让exec自己在那运行,php语句不等待,自己运行下去,让浏览器不用等待。谢谢。

Note:
如何程序使用此函数启动,为了能保持在后台运行,此程序必须将输出重定向到文件或其它输出流。 否则会导致 PHP 挂起,直至程序执行结束。
exec("命令 > null");

来自:http://zhidao.baidu.com/link?url=sqz2GSYfd3fJWE5F7F_2AR15zpj6VNe-9jc1pMNmmj-3MB5KHOnbzOB_9Dls43TqL1zH0PZmdZuN1AXSc_Xj-_

——————————————————————————————————————————————————————————————
请问在php程序里如何非阻塞地执行另一个.php脚本?

我们知道在命令行里可以用php XX.php调用一个php脚本,
但是在php程序里怎样调用另一个.php脚本呢?
要求有两个:
(1) 非阻塞式的。即主程序执行调用其他脚本的语句后,继续执行下面的语句而不阻塞。
(2) 能否把一些主程序的对象作为参数传给被调用的脚本?可以以变通的方式。

exec("php XX.php")函数貌似不行,因为exec()是阻塞的。
请大家想想办法,如何满足以上这两个解决问题?谢谢!


刚看了看Process Control Functions的说明(英文的没看太明白).不过看到了pcntl_fork()复制进程.
这个和Perl的fork()差不多能实现.不过Process Control Functions不能在windows下使用啊,只能在unix或linux下用.比较不爽啊!!!!!
示範 1.pcntl_fork() example

主进程执行当前程序,让子进程去调用另一个php脚本吧,这不就不阻塞了吗!!!


来自:http://bbs.phpchina.com/thread-23687-1-1.html


当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施:

一、若你使用的是FastCGI模式,使用fastcgi_finish_request()能马上结束会话,但PHP线程继续在跑。

这个例子输出结果可看到输出program start.后会话就返回了,所以debug那个输出浏览器是接收不到的,而log.txt文件能完整接收到三个完成时间。

二、使用fsockopen的非阻塞模式请求另外的网址

三、使用Gearman
Gearman是一个具有php扩展的分布式异步处理框架,能处理大批量异步任务。
摘自:http://blog.4wer.com/php-nonblock
PHP中实现非阻塞模式:
http://blog.csdn.net/linvo/article/details/5466046
背景:项目之前是在jsp下,现在想切换成php,如何在nginx中配置运行无扩展名的php文件,或运行不是.php扩展名的文件呢?本文为大家介绍的方法,你可以参考下。
根据下面实践好像不行,出现403:"GET /ICU_UP/clientupload.jsp HTTP/1.0" 403 35
于是修改成urlrewrite格式,如下:


/ICU_UP/clientupload.jsp
转写成:
/ICU_UP/clientupload.php

阅读全文
扩展编译好用,通过php编码测试报“段错误",如果是c语言都是用gdb进行设置,那php扩展要如何进行调试呢?搜索了下,虽然是php扩展但是core是php 的core不是单个so扩展的coredump
这里使用ulimit -c unlimited来开启core文件,使用gdb来对core文件进行调试演示一下。
阅读全文
背景:cache有多台,addServer,这块里有一个算法不是太好,在腾讯时在做云存储时有兄弟改成了环形算法,更能最大限度的在添加机器后影响小,这块我目前没几台机器没有这个必要,自己写还不如这位兄弟写的,特转。
阅读全文
背景:用Tokeyo (这个数据库好像没再理新了)做一些队列啥的,做一些C的多线程上传啥的,用来存下数据,相当有用,PHP也能存放些数组啥的,结构简单,高效、稳定、可靠。
如何启动ttserver:

定时删除TTserver的ulog日志:


PHP扩展的Tokyo Tyrant安装配置及测试
一,安装
[root@localhost ]# wget http://pecl.php.net/get/tokyo_tyrant-0.5.0.tgz
[root@localhost ]# tar zxvf tokyo_tyrant-0.5.0.tgz
[root@localhost ]# phpize
如果系统没有安装phpize
安装: yum install php-devel   ,
因为PHPize 是属于php 的 devel .
然后进入目录:
[root@localhost tokyo_tyrant-0.5.0]# phpize
./configure
make && make install

如果configure的报错:
checking that Tokyo Tyrant is at least version 1.1.24... yes
checking for Tokyo Cabinet... not found
configure: error: Please reinstall the Tokyo Cabinet distribution

在config.m4里有写:
PHP_ARG_WITH(tokyo-tyrant, whether to enable tokyo tyrant support,
[  --with-tokyo-tyrant[=DIR]       Enable tokyo tyrant support. DIR is the prefix to Tokyo Tyrant installation directory.], yes)
PHP_ARG_WITH(tokyo-cabinet-dir, directory of the Tokyo Cabinet installation,
[  --with-tokyo-cabinet-dir[=DIR]       DIR is the prefix to Tokyo Cabinet installation directory.], yes)
PHP_ARG_ENABLE(tokyo-tyrant-session, whether to enable tokyo tyrant session handler support,
[  --disable-tokyo-tyrant-session    Disables tokyo tyrant session handler support], yes, no)
指定TT和TC的路径就好了
./configure --with-tokyo-tyrant=/usr/local/tokyotyrant   --with-tokyo-cabinet-dir=/usr/local/tokyocabinet

安装完成以后,在php.ini里面增加一行extension = tokyo_tyrant.so,然后tt扩展就生效了。
debian:/home/software# php -m | grep tokyo
tokyo_tyrant
二,测试
<?php
$tt = new TokyoTyrant("localhost");
$tt->put("language", "C/C++");
echo 'language:' . $tt->get("language") . "/n";

echo 'The count of records is:' . $tt -> num() . "/n";

print_r($tt -> stat());

$it = $tt -> getIterator();
foreach ($it as $key => $val) {
     echo "key: $key, val: $val/n";
}
?>

telnet localhost 2011
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get language
VALUE language 0 5
C/C++
END

php tt.php | more
language:C/C++
The count of records is:498
Array
(
     [version] => 1.1.40
     [libver] => 323
     [protver] => 0.91
     [os] => Linux
     [time] => 1283855111.219663
     [pid] => 1824
     [sid] => 0
     [type] => hash
     [path] => /home/ttserver/database.tch
     [rnum] => 498
     [size] => 568784
     [bigend] => 0
     [fd] => 7
     [loadavg] => 0.150000
     [memsize] => 145842176
     [memrss] => 2265088
     [ru_user] => 0.596037
     [ru_sys] => 30.269891
     [ru_real] => 3065.307271
     [cnt_put] => 6
     [cnt_putkeep] => 0
     [cnt_putcat] => 0
     [cnt_putshl] => 0
     [cnt_putnr] => 0
     [cnt_out] => 0
     [cnt_get] => 1003
     [cnt_mget] => 0
     [cnt_vsiz] => 0
     [cnt_iterinit] => 4
     [cnt_iternext] => 998
     [cnt_fwmkeys] => 0
     [cnt_addint] => 0
     [cnt_adddouble] => 0
     [cnt_ext] => 0
     [cnt_sync] => 0
     [cnt_optimize] => 0
     [cnt_vanish] => 0
     [cnt_copy] => 0
     [cnt_restore] => 0
     [cnt_setmst] => 0
     [cnt_rnum] => 2
     [cnt_size] => 0
     [cnt_stat] => 1
     [cnt_misc] => 0
     [cnt_repl] => 0
     [cnt_put_miss] => 0
     [cnt_out_miss] => 0
     [cnt_get_miss] => 0
)
key: metaData_default_1, val: {"songname":"bb","specialname":"cc"}
key: metaData_default_2, val: {"songname":"bb","specialname":"cc"}
key: metaData_default_3, val: {"songname":"cc","specialname":"cc"}
key: metaData_default_4, val: {"songname":"dd","specialname":""}
key: metaData_default_5, val: {"songname":"ee","specialname":"ee"}
key: top_item_default, val: [{"songid":"1","songname":"bb","specialname":"cc"},{"songid":
"2","songname":"bb","specialname":"cc"},{"songid":"3","songname":"cc","specialname":"cc"}
,{"songid":"4","songname":"dd","specialname":""},{"songid":"5","songname":"ee","specialna
me":"ee"}]
.....


三,PHP调用MEMCACHE处理TT的PHP例子(实践OK):

序列化问题
   如果你熟悉memcache协议,或者你曾经用php的memcache来使用ttserver,你可能马上就发现了上面的问题。
比如我们key3是一个数组,但是我们取回来的是一个序列化的字符串,没有自动反序列化,在memcached服务器上是会
自动反序列化的。
    通过上面的telnet示例我们可以看到,我们add key1的时候设置flag参数为1,但是我们get回来的时候,返回的flag参数是0,实际上,ttserver是没有存储flag参数的,统一的都使用0,这就造成了php使用时不会自动反序列化,当然,如果你使用压缩参数,一样会有这样的问题。
    怎么样解决这个问题,如果要修改ttserver的代码实为不方便。我们完全可以在php,或者我们的客户端来控制。
比如value我们统一的都序列化后存储,取出来的时候我们再反序列化。
print_r(unserialize($mem->get("name2")));  

Run:
[root@test tokyo_tyrant-0.5.0]# php mem.php
lalala<hr>a:1:{s:6:"hahaha";s:13:"this is name2";}Array
(
    [hahaha] => this is name2
)

From:http://www.cnblogs.com/sunli/archive/2009/03/18/1415168.html
四,PHP直接调用TOKYO TYRANT处理TT的PHP例子
<?php
        try {
            $tt = new TokyoTyrant("192.168.1.80", 2011);
        }catch (TokyoTyrantException $e) {
            var_dump($e);
            exit;
        }
        $tt->put("ceshi1", "aaaaaaaaaaaaa");
        echo $tt->get("ceshi1");
?>

————————————————————————————————————————————————————————
1、创建Tokyo Tyrant数据文件存放目录
mkdir -p /ttserver/
2、启动Tokyo Tyrant主进程
运行之前要设置lib搜索路径,否则会提示找不到库文件
echo '/usr/local/lib' >> /etc/ld.so.conf
ldconfig -v
ulimit -SHn 51200
1)单机模式:


实践如下:
ttserver -host 127.0.0.1 -port 11111 -thnum 8 -dmn -pid /ttserver/ttserver.pid -log /ttserver/ttserver.log -le -ulog /ttserver/ -ulim 128m -sid 1 -rts /ttserver/ttserver.rts /ttserver/database.tch

2)互为主辅:
注:数据库类型由后缀决定,因为我只需要key-value的功能,所以采用功能简单,速度快的hash database
Hash Database :.tch
B+ tree database :.tcb
fixed-length database :.tcf
table database :.tct
内存Hash Database :*
内存B+ tree database :+
服务器 192.168.1.110

ulimit -SHn 51200
ttserver -host 192.168.1.110 -port 11111 -thnum 8 -dmn -pid /ttserver/ttserver.pid -log /ttserver/ttserver.log -le -ulog /ttserver/ -ulim 128m -sid 110 -mhost 192.168.1.92 -mport 11111 -rts /ttserver/ttserver.rts /ttserver/database.tch
服务器 192.168.99.111

ulimit -SHn 51200
ttserver -host 192.168.1.111 -port 11111 -thnum 8 -dmn -pid /ttserver/ttserver.pid -log /ttserver/ttserver.log -le -ulog /ttserver/ -ulim 128m -sid 111 -mhost 192.168.1.91 -mport 11111 -rts /ttserver/ttserver.rts /ttserver/database.tch
3)参数说明
ttserver [-host name] [-port num] [-thnum num] [-tout num] [-dmn] [-pid path] [-log path] [-ld|-le] [-ulog path] [-ulim num] [-uas] [-sid num] [-mhost name] [-mport num] [-rts path] [dbname]
  -host name : 指定需要绑定的服务器域名或IP地址。默认绑定这台服务器上的所有IP地址。
  -port num : 指定需要绑定的端口号。默认端口号为1978
  -thnum num : 指定线程数。默认为8个线程。
  -tout num : 指定每个会话的超时时间(单位为秒)。默认永不超时。
  -dmn : 以守护进程方式运行。
  -pid path : 输出进程ID到指定文件(这里指定文件名)。
  -log path : 输出日志信息到指定文件(这里指定文件名)。
  -ld : 在日志文件中还记录DEBUG调试信息。
  -le : 在日志文件中仅记录错误信息。
  -ulog path : 指定同步日志文件存放路径(这里指定目录名)。
  -ulim num : 指定每个同步日志文件的大小(例如128m)。
  -uas : 使用异步IO记录更新日志(使用此项会减少磁盘IO消耗,但是数据会先放在内存中,不会立即写入磁盘,如果重启服务器或ttserver进程被kill掉,将导致部分数据丢失。一般情况下不建议使用)。
  -sid num : 指定服务器ID号(当使用主辅模式时,每台ttserver需要不同的ID号)
  -mhost name : 指定主辅同步模式下,主服务器的域名或IP地址。
  -mport num : 指定主辅同步模式下,主服务器的端口号。
  -rts path : 指定用来存放同步时间戳的文件名。
3、停止ttserver进程
ps aux | grep ttserver | grep -v 'grep' | awk -F ' ' '{print $2}' | xargs kill -TERM

PHP扩展安装包下载:wget http://pecl.php.net/get/tokyo_tyrant-0.5.0.tgz
数据库安装包下载:http://download.csdn.net/download/hx_jinqiang/2665655
来自:http://wenku.baidu.com/link?url=g6AkcZK9EDbWJxD-WjRzd-hCYaN0Gvhbpgdd-g5dLtDydQppbENPiZaBOAw-Ia9tLTpVZgLOPYolCG3-5ioXUO19c41oAsEwvv8ElKqyqrC
Tokyo Cabinet和Tokyo Tyrant安装和调用手记:
http://blog.csdn.net/grantxx/article/details/7547492
背景:大文件的断点续传,有时网络波动啥的,需要断点从已经下载位置续传下载文件,对于没有传过的文件再次从开始下载就麻烦了,这块http协议支持的,Apache和Nginx都支持这样的方法实现了从某个部分进行断点下载。
服务器是否支持断点续传的判断:
更多 0
断点续传 linux wget 服务器 curl
通常情况下,Web服务器(如Apache)会默认开启对断点续传的支持。因此,如果直接通过Web服务器来提供文件的下载,可以不必做特别的配置,即可享受到断点续传的好处。断点续传是在发起HTTP请求的时候加入RANGE头来告诉服务器客户端已经下载了多少字节。等所有这些请求都返回之后,再把得到的内容一块一块的拼接起来得到完整的资源。

Resumable download file Web服务器(如Apache)默认开启断点续传

你可以通过以下的命令来测试一下。

Linux 测试服务器是否支持断点续传

localhost [~]# wget -S http://httpd.apache.org/images/httpd_logo_wide_new.png 2>&1 | grep ‘Accept-Ranges’
  Accept-Ranges: bytes

输出结果 Accept-Ranges: bytes ,说明服务器支持按字节下载。

curl 命令发送字节范围下载

curl –range 0-99 http://images.apple.com/home/images/billboard_iphone_hero.jpg

这样可以到最开始99字节,结果如下图:

curl range bytes request curl 命令发送字节范围请求

说明从服务器端按字节范围下载是完全没有问题的。

现在我们尝试以下方式:

1、一次性下载整个图片。

localhost [~]# curl –range 0-98315 http://images.apple.com/home/images/billboard_iphone_hero.jpg > test.jpg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 98316  100 98316    0     0   524k      0 –:–:– –:–:– –:—:—  527k

完成后,test.jpg完全等于billboard_iphone_hero.jpg,文件大小为98,316 字节。

实践如下:我的Nginx服务器,请求下看是否支持,如下:
1)实践下下载这块的header返回头有Accept-Ranges: bytes证明Nginx也是支持断点续传下载的:



(1)Curl包含range的请求头是这样的:

(2)其抓包Nginx的返回头是这样:
HTTP/1.1 206 Partial Content
Server: nginx
Date: Wed, 19 Nov 2014 14:45:07 GMT
Content-Type: image/jpeg
Content-Length: 109
Last-Modified: Fri, 07 Nov 2014 05:06:12 GMT
Connection: keep-alive
ETag: "545c5344-1b8c"
Expires: Fri, 19 Dec 2014 14:45:07 GMT
Cache-Control: max-age=2592000
Content-Range: bytes 0-108/7052


4)通过前面的curl及wget联合起来,先后组合起来实现一个断点下载整个图片,并看其服务器返回头(curl已经下了前面的108,后从109开始wget:
(1)先保存一部分到108:


(2)再通过wget的断点续传下载命令-c,请求剩下的部分(Content-Range: bytes 109-7051/7052):
A)加上-S看返回头, -S,  --server-response         打印服务器响应。:


B)发起头如下,也就是说经curl保存一部分后,wget通过-c参数时,后面它会去读取目前文件大小,后写在http头里去找服务端要,请求头如下:


注意:字节是从0开始,结束字节为总字节长度 减 1。
来自:http://ju.outofmemory.cn/entry/23646
Nginx:http://chenzhenianqing.cn/articles/926.html
阅读全文
今天用PHP读取一个接口的数据使用了iconv转换字符编码格式,出现Notice: iconv(): Unknown error (84) :

上面这行摘自:http://jackxiang.com/post/1057/
最后,修改为如下:

———————————————————————————————————————————————————
读其官方文档 http://www.php.net/manual/en/function.iconv.php对参数out_charset的解释:
The output charset.
If you append the string //TRANSLIT to out_charset transliteration is activated. This means that when a character can’t be represented in the target charset, it can be approximated through one or several similarly looking characters. If you append the string //IGNORE, characters that cannot be represented in the target charset are silently discarded. Otherwise, str is cut from the first illegal character and an E_NOTICE is generated.

大概的意思就是:
如果你加上 //TRANSLIT 到out_charset 的参数后面,意味着如果找不到目标编码,则程序会去找与其相近的编码。如果你加的是//IGNORE,则不会去找相近的编码,而且只要有一个字符是程序无法识别的则将会报错。
根据上面的解释我将代码
iconv('gb2312','utf-8', serialize($storeData));
改为
iconv('gb2312','utf-8//TRANSLIT//IGNORE', serialize($storeData));

这样就ok了!

来自:http://www.tonitech.com/822.html
E513: 写入错误,转换失败 (请将 'fenc' 置空以强制执行) 警告: 原始文件可能已丢失或损坏 在文件正确写入前请勿退出编辑器!

set fenc=
来自:
http://forum.ubuntu.org.cn/viewtopic.php?p=2498184
背景:在用c获取root后,执行一个命令退出时,报exit logout TERM environment variable not set.

# to avoid the error: TERM environment variable not set.
#
TERM=linux
export TERM
clear

摘自:http://bbs.chinaunix.net/thread-2070668-1-1.html
背景:以前调试PHP如CPU100%发生在哪儿,用GDB,现在PHP自己带了一个PHPGDB,方便调试。


root@119.10.6.23:/data/codesdev/phpServer# php test.php
root@119.10.6.23:/data/software/lnmp1.1-full/php-5.6.0# ps aux|grep test.php
root      4071  1.3  1.5 350356 92040 pts/1    S+   11:37   0:00 php test.php
cli方式执行php脚本,加入执行的进程号为4071。我们使用gdb命令来调试进程。
root@119.10.6.23:/data/software/lnmp1.1-full/php-5.6.0# gdb -p 4071

(gdb) print (char *)executor_globals.active_op_array->filename
$1 = 0x2ad61b4c8c48 "/data/codesdev/phpServer/test.php"
(gdb) print (char *)executor_globals.active_op_array->function_name
$2 = 0x2ad61b4c8d50 "test1"
(gdb)  print executor_globals->current_execute_data->opline->lineno
$3 = 4
(gdb)  print executor_globals->current_execute_data->opline->lineno
$4 = 4
很显然,他正在执行第四行的sleep方法。
如果上面的方法你感觉麻烦,那你可以使用.gdbinit文件。这个文件在php源码的根目录下。使用方法如下:


题外话:
​从php5.6开始,php中集成了一个phpdbg的工具。可以像gdb调试c语言程序一样,调试php程序。感兴趣的话,可以打开下面的连接看看。
https://wiki.php.net/rfc/phpdbg
http://phpdbg.com/docs
来自:http://www.searchtb.com/2014/04/当cpu飙升时,找出php中可能有问题的代码行.html
————————————————————————————————————————————————————————————
phpdbg 作为一个交互式集成的调试器SAPI:
http://phpdbg.com/
Download:
https://codeload.github.com/krakjoe/phpdbg/legacy.zip/v0.4.0
Unzip:
root@119.10.6.23:/data/software/lnmp1.1-full/php-5.6.0/ext/krakjoe-phpdbg-cee9645#

http://phpdbg.com/docs
Installation
To install phpdbg, you must compile the source against your PHP installation sources, and enable the SAPI with the configure command.

cd /usr/src/php-src/sapi
git clone https://github.com/krakjoe/phpdbg
cd ../
./buildconf --force
./config.nice
make -j8
make install-phpdbg

phpdbg  Felipe Pena, Joe Watkins, Bob Weinand
Command Line Options
The following switches are implemented (just like cli SAPI):

-n ignore php ini
-c search for php ini in path
-z load zend extension
-d define php ini entry
The following switches change the default behaviour of phpdbg:

-v disables quietness
-s enabled stepping
-e sets execution context
-b boring - disables use of colour on the console
-I ignore .phpdbginit (default init file)
-i override .phpgdbinit location (implies -I)
-O set oplog output file
-q do not print banner on startup
-r jump straight to run
-E enable step through eval()
Note: passing -rr will cause phpdbg to quit after execution, rather than returning to the console
背景:开php-fpm的9000端口,有时配置出错会出现502,特别转载。
不要总看nginx 的日志文件。
对于开端口这种事情,listen.allowed_clients 里逗号分割不能有空格!
[www]
listen = 10.11.80.49:9000
listen.allowed_clients = 10.11.80.47,10.11.80.48, 10.11.80.49

阅读全文
背景:有可能 fastcgi Connection reset by peer于502共同发生,(参看:https://jackxiang.com/post/4710/ ,http://www.jb51.net/article/50408.htm 写道:很多站长转到nginx+php-fpm后,饱受500,502问题困扰。当nginx收到如上错误码时,可以确定后端php-fpm解析php出了某种问题,比如,执行错误,执行超时。php-fpm.conf的配置文件中有一个参数request_slowlog_timeout。 )。注意nginx的notice日志及php的request_slowlog_timeout日志。
1)nginx:
在nginx的全局配置中增加 : error_log   logs/error.log notice;

nginx记录日志信息分两个级别,第一个级别的取值为如下之一:
“stderr”, “emerg”, “alert”, “crit”, “error”,”warn”, “notice”, “info”, “debug”
这些值是互斥的,也就是说只能取其中之一,如果在配置文件里加了像如下这种两条配置项:
error_log  logs/error.log  notice;
error_log  logs/error.log  info;

2)php的php-fpm.conf增加时间长度限定超过就算超时:
当PHP运行在php-fpm模式下,php.ini配置的max_execute_time是无效的,需要在php-fpm.conf中配置另外一个配置项:request_terminate_timeout;
request_terminate_timeout = 10
request_slowlog_timeout = 0
slowlog = /data/logs/php/slow.log
    当request_slowlog_timeout 设为一个具体秒时request_slowlog_timeout =5,表示如果哪个脚本执行时间大于5秒,会记录这个脚本到慢日志文件中
request_slowlog_timeout =0表示关闭慢日志输出。
摘自:http://blog.csdn.net/zhangxinrun/article/details/17002939

下面是php 5.3以上版本将TCP改成socket方式的配置方法:
修改php-fpm.conf(/usr/local/php/etc/php-fpm.conf)
;listen = 127.0.0.1:9000
listen = /dev/shm/php-cgi.sock
nginx通过unix socket和fastcgi通信,比tcp socket要高效,重负荷下可以考虑。
1、在nginx.conf中修改配置为:
fastcgi_pass unix:/tmp/php-cgi.sock;
#fastcgi_pass 127.0.0.1:9000;
2、在php-fpm.conf中修改配置为:
/tmp/php-cgi.sock
同理,在proxy_pass、upstream server 等处都能使用

言归正传:
Connection reset by peer
这个错误是在nginx的错误日志中发现的,为了更全面的掌握nginx运行的异常,强烈建议在nginx的全局配置中增加
error_log   logs/error.log notice;
这样,就可以记录nginx的详细异常信息。


nginx的错误日志中会出现Connection reset by peer) while reading response header from upstream, client: 1.1.1.1, server: 102.local, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000

后来反复检查,发现这是因为php运行较慢,并超出php-fpm.conf的request_terminate_timeout设置的秒数。

request_terminate_timeout用于设置当某个php脚本运行最长时间,若超出php-fpm进程管理器强行中止当前程序,并关闭fastcgi和nginx的网络连接,然后nginx中就会出现Connection reset by peer的错误了。

也就是说,产生这个错误的原因是:
php 程序的运行时间超出request_terminate_timeout设置的值。
在php-fpm环境下,在php的安装目录的etc/php-fpm.conf中有此值的设置项,可将其设置为0或更大的值。

提示,在php.ini中存在一项max_execution_time,也用于设置php脚本的最长执行时间。但在php-fpm环境下,我发现max_execution_time的设置是无效的,只有request_terminate_timeout产生了作用。

总结:请将request_terminate_timeout设置为较大的值或0,可减少因php脚本执行时行过长导致nginx产生Connection reset by peer错误。

转自:http://zhangxugg-163-com.iteye.com/blog/1310311
背景:最近升级mysql到: 5.6.21,PHP也升级到php-5.6.0,发现博客成乱码了。
解决办法:
my.cnf


备注:
Php升级为5.6.0后注意OPCache生成扩展路径和PHP5.5.32位置不一样,否则会报:
The Zend Engine API version 220131226 which is installed, is newer.
分页: 7/24 第一页 上页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 下页 最后页 [ 显示模式: 摘要 | 列表 ]