包含behaviorphp的词条

华为云服务器特价优惠火热进行中!

2核2G2兆仅需 38 元;4核4G3兆仅需 79 元。购买时间越长越优惠!更多配置及优惠价格请咨询客服。

合作流程:
1、点击链接注册/关联华为云账号:点击跳转
2、添加客服微信号:cloud7591,确定产品方案、价格方案、服务支持方案等;
3、客服协助购买,并拉微信技术服务群,享受一对一免费技术支持服务;
技术专家在金蝶、华为、腾讯原厂有多年工作经验,并已从事云计算服务8年,可对域名、备案、网站搭建、系统部署、AI人工智能、云资源规划等上云常见问题提供更专业靠谱的服务,对相应产品提供更优惠的报价和方案,欢迎咨询。

本篇文章给大家谈谈behaviorphp,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

微信号:cloud7591
如需了解更多,欢迎添加客服微信咨询。
复制微信号

本文目录一览:

thinkphp 怎么调用behavior

看不明白你的问题,但是我知道定时任务都是需要服务器配合设置才行

面试的问我 thinkphp核心构架是什么?

ThinkPHP的架构: 是 核心 + 行为 + 驱动,TP官方简称为:CBD\x0d\x0a\x0d\x0a核心(Core):就是框架的核心代码,不可缺少的东西,TP本身是基于MVC思想开发的框架。\x0d\x0a\x0d\x0a行为(Behavior) :行为在新版ThinkPHP的架构里面起着举足轻重的作用,在系统核心之上,设置了很多标签扩展位,而每个标签位置可以依次执行各自的独立行为。行为扩展就因此而诞生了,而且很多系统功能也是通过内置的行为扩展完成的,所有行为扩展都是可替换和增加的,由此形成了底层框架可组装的基础。\x0d\x0a\x0d\x0a驱动( Driver ):数据库驱动、缓存驱动、标签库驱动和模板引擎驱动,以及外置的类扩展。\x0d\x0a\x0d\x0a答案部分来自【知乎】

几种常见的PHP超时处理方法

【Web服务器超时处理】

[ Apache ]

一般在性能很高的情况下,缺省所有超时配置都是30秒,但是在上传文件,或者网络速度很慢的情况下,那么可能触发超时操作。

目前apachefastcgiphp-fpm模式下有三个超时设置:

fastcgi超时设置:

修改的fastcgi连接配置,类似如下:

复制代码 代码如下:

IfModulemod_fastcgi.c

FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sock

ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"

AddHandlerphp-fastcgi.php

Actionphp-fastcgi/fcgi-bin/php-cgi

AddTypeapplication/x-

/IfModule

缺省配置是30s,如果需要定制自己的配置,需要修改配置,比如修改为100秒:(修改后重启apache):

复制代码 代码如下:

IfModulemod_fastcgi.c

FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/php-cgi-socket/home/forum/php5/etc/php-fpm.sock-idle-timeout100

ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"

AddHandlerphp-fastcgi.php

Actionphp-fastcgi/fcgi-bin/php-cgi

AddTypeapplication/x-

/IfModule

如果超时会返回500错误,断开跟后端php服务的连接,同时记录一条apache错误日志:

[ThuJan2718:30:152011][error][client10.81.41.110]FastCGI:commwithserver"/home/forum/apache/apache_php/cgi-bin/php-cgi"aborted:idletimeout(30sec)

[ThuJan2718:30:152011][error][client10.81.41.110]FastCGI:incompleteheaders(0bytes)receivedfromserver"/home/forum/apache/apache_php/cgi-bin/php-cgi"

其他fastcgi配置参数说明:

复制代码 代码如下:

IdleTimeout发呆时限

ProcessLifeTime一个进程的最长生命周期,过期之后无条件kill

MaxProcessCount最大进程个数

DefaultMinClassProcessCount每个程序启动的最小进程个数

DefaultMaxClassProcessCount每个程序启动的最大进程个数

IPCConnectTimeout程序响应超时时间

IPCCommTimeout与程序通讯的最长时间,上面的错误有可能就是这个值设置过小造成的

MaxRequestsPerProcess每个进程最多完成处理个数,达成后自杀

[ Lighttpd ]

配置:lig

Lighttpd配置中,关于超时的参数有如下几个(篇幅考虑,只写读超时,写超时参数同理):

主要涉及选项:

server.max-keep-alive-idle=5

server.max-read-idle=60

server.read-timeout=0

server.max-connection-idle=360

复制代码 代码如下:

#每次keep-alive的最大请求数,默认值是16

server.max-keep-alive-requests=100

#keep-alive的最长等待时间,单位是秒,默认值是5

server.max-keep-alive-idle=1200

#lighttpd的work子进程数,默认值是0,单进程运行

server.max-worker=2

#限制用户在发送请求的过程中,最大的中间停顿时间(单位是秒),

#如果用户在发送请求的过程中(没发完请求),中间停顿的时间太长,lighttpd会主动断开连接

#默认值是60(秒)

server.max-read-idle=1200

#限制用户在接收应答的过程中,最大的中间停顿时间(单位是秒),

#如果用户在接收应答的过程中(没接完),中间停顿的时间太长,lighttpd会主动断开连接

#默认值是360(秒)

server.max-write-idle=12000

#读客户端请求的超时限制,单位是秒,配为0表示不作限制

#设置小于max-read-idle时,read-timeout生效

server.read-timeout=0

#写应答页面给客户端的超时限制,单位是秒,配为0表示不作限制

#设置小于max-write-idle时,write-timeout生效

server.write-timeout=0

#请求的处理时间上限,如果用了mod_proxy_core,那就是和后端的交互时间限制,单位是秒

server.max-connection-idle=1200

说明:

对于一个keep-alive连接上的连续请求,发送第一个请求内容的最大间隔由参数max-read-idle决定,从第二个请求起,发送请求内容的最大间隔由参数max-keep-alive-idle决定。请求间的间隔超时也由max-keep-alive-idle决定。发送请求内容的总时间超时由参数read-timeout决定。Lighttpd与后端交互数据的超时由max-connection-idle决定。

延伸阅读:

[ Nginx ]

配置:nf

复制代码 代码如下:

http{

#Fastcgi:(针对后端的fastcgi生效,fastcgi不属于proxy模式)

fastcgi_connect_timeout5;#连接超时

fastcgi_send_timeout10; #写超时

fastcgi_read_timeout10;#读取超时

#Proxy:(针对proxy/upstreams的生效)

proxy_connect_timeout15s;#连接超时

proxy_read_timeout24s;#读超时

proxy_send_timeout10s; #写超时

}

说明:

Nginx 的超时设置倒是非常清晰容易理解,上面超时针对不同工作模式,但是因为超时带来的问题是非常多的。

延伸阅读:

ml

ml

ml

【PHP本身超时处理】

[ PHP-fpm ]

配置:nf

复制代码 代码如下:

?xmlversion="1.0"?

configuration

//...

Setsthelimitonthenumberofsimultaneousrequeststhatwillbeserved.

EquivalenttoApacheMaxClientsdirective.

EquivalenttoPHP_FCGI_CHILDRENenvironmentinoriginalphp.fcgi

Usedwithanypm_style.

#php-cgi的进程数量

valuename="max_children"128/value

Thetimeout(inseconds)forservingasinglerequestafterwhichtheworkerprocesswillbeterminated

Shouldbeusedwhen'max_execution_time'inioptiondoesnotstopscriptexecutionforsomereason

'0s'means'off'

#php-fpm 请求执行超时时间,0s为永不超时,否则设置一个 Ns 为超时的秒数

valuename="request_terminate_timeout"0s/value

Thetimeout(inseconds)forservingofsinglerequestafterwhichaphpbacktracewillbedumpedtoslow.logfile

'0s'means'off'

valuename="request_slowlog_timeout"0s/value

/configuration

说明:

在php.ini中,有一个参数max_execution_time可以设置PHP脚本的最大执行时间,但是,在php-cgi(php-fpm)中,该参数不会起效。真正能够控制PHP脚本最大执行时:

valuename="request_terminate_timeout"0s/value

就是说如果是使用mod_php5.so的模式运行max_execution_time是会生效的,但是如果是php-fpm模式中运行时不生效的。

延伸阅读:

[ PHP ]

配置:php.ini

选项:

max_execution_time=30

或者在代码里设置:

ini_set("max_execution_time",30);

set_time_limit(30);

说明:

对当前会话生效,比如设置0一直不超时,但是如果php的safe_mode打开了,这些设置都会不生效。

效果一样,但是具体内容需要参考php-fpm部分内容,如果php-fpm中设置了request_terminate_timeout的话,那么max_execution_time就不生效。

【后端接口访问超时】

【HTTP访问】

一般我们访问HTTP方式很多,主要是:curl,socket,file_get_contents()等方法。

如果碰到对方服务器一直没有响应的时候,我们就悲剧了,很容易把整个服务器搞死,所以在访问http的时候也需要考虑超时的问题。

[ CURL 访问HTTP]

CURL 是我们常用的一种比较靠谱的访问HTTP协议接口的lib库,性能高,还有一些并发支持的功能等。

CURL:

curl_setopt($ch,opt)可以设置一些超时的设置,主要包括:

*(重要)CURLOPT_TIMEOUT设置cURL允许执行的最长秒数。

*(重要)CURLOPT_TIMEOUT_MS设置cURL允许执行的最长毫秒数。(在cURL7.16.2中被加入。从PHP5.2.3起可使用。)

CURLOPT_CONNECTTIMEOUT在发起连接前等待的时间,如果设置为0,则无限等待。

CURLOPT_CONNECTTIMEOUT_MS尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。在cURL7.16.2中被加入。从PHP5.2.3开始可用。

CURLOPT_DNS_CACHE_TIMEOUT设置在内存中保存DNS信息的时间,默认为120秒。

curl普通秒级超时:

$ch=curl_init();

curl_setopt($ch,CURLOPT_URL,$url);

curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);

curl_setopt($ch,CURLOPT_TIMEOUT,60);//只需要设置一个秒的数量就可以

curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);

curl_setopt($ch,CURLOPT_USERAGENT,$defined_vars['HTTP_USER_AGENT']);

curl普通秒级超时使用:

curl_setopt($ch,CURLOPT_TIMEOUT,60);

curl如果需要进行毫秒超时,需要增加:

curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1L);

或者是:

curl_setopt($ch,CURLOPT_NOSIGNAL,true);是可以支持毫秒级别超时设置的

curl一个毫秒级超时的例子:

复制代码 代码如下:

?php

if(!isset($_GET['foo'])){

//Client

$ch=curl_init('');

curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);

curl_setopt($ch,CURLOPT_NOSIGNAL,1);//注意,毫秒超时一定要设置这个

curl_setopt($ch,CURLOPT_TIMEOUT_MS,200);//超时毫秒,cURL7.16.2中被加入。从PHP5.2.3起可使用

$data=curl_exec($ch);

$curl_errno=curl_errno($ch);

$curl_error=curl_error($ch);

curl_close($ch);

if($curl_errno0){

echo"cURLError($curl_errno):$curl_errorn";

}else{

echo"Datareceived:$datan";

}

}else{

//Server

sleep(10);

echo"Done.";

}

?

其他一些技巧:

1. 按照经验总结是:cURL版本=libcurl/7.21.0版本,毫秒级超时是一定生效的,切记。

2. curl_multi的毫秒级超时也有问题。。单次访问是支持ms级超时的,curl_multi并行调多个会不准

[流处理方式访问HTTP]

除了curl,我们还经常自己使用fsockopen、或者是file操作函数来进行HTTP协议的处理,所以,我们对这块的超时处理也是必须的。

一般连接超时可以直接设置,但是流读取超时需要单独处理。

自己写代码处理:

复制代码 代码如下:

$tmCurrent=gettimeofday();

$intUSGone=($tmCurrent['sec']-$tmStart['sec'])*1000000

+($tmCurrent['usec']-$tmStart['usec']);

if($intUSGone$this-_intReadTimeoutUS){

returnfalse;

}

或者使用内置流处理函数stream_set_timeout()和stream_get_meta_data()处理:

复制代码 代码如下:

?php

//Timeoutinseconds

$timeout=5;

$fp=fsockopen("",80,$errno,$errstr,$timeout);

if($fp){

fwrite($fp,"GET/HTTP/1.0rn");

fwrite($fp,"Host:rn");

fwrite($fp,"Connection:Closernrn");

stream_set_blocking($fp,true);//重要,设置为非阻塞模式

stream_set_timeout($fp,$timeout);//设置超时

$info=stream_get_meta_data($fp);

while((!feof($fp))(!$info['timed_out'])){

$data.=fgets($fp,4096);

$info=stream_get_meta_data($fp);

ob_flush;

flush();

}

if($info['timed_out']){

echo"ConnectionTimedOut!";

}else{

echo$data;

}

}

file_get_contents超时:

复制代码 代码如下:

?php

$timeout=array(

'http'=array(

'timeout'=5//设置一个超时时间,单位为秒

)

);

$ctx=stream_context_create($timeout);

$text=file_get_contents("",0,$ctx);

?

fopen超时:

复制代码 代码如下:

?php

$timeout=array(

'http'=array(

'timeout'=5//设置一个超时时间,单位为秒

)

);

$ctx=stream_context_create($timeout);

if($fp=fopen("","r",false,$ctx)){

while($c=fread($fp,8192)){

echo$c;

}

fclose($fp);

}

?

【MySQL】

php中的mysql客户端都没有设置超时的选项,mysqli和mysql都没有,但是libmysql是提供超时选项的,只是我们在php中隐藏了而已。

那么如何在PHP中使用这个操作捏,就需要我们自己定义一些MySQL操作常量,主要涉及的常量有:

MYSQL_OPT_READ_TIMEOUT=11;

MYSQL_OPT_WRITE_TIMEOUT=12;

这两个,定义以后,可以使用options设置相应的值。

不过有个注意点,mysql内部实现:

1.超时设置单位为秒,最少配置1秒

2.但mysql底层的read会重试两次,所以实际会是3秒

重试两次+ 自身一次=3倍超时时间,那么就是说最少超时时间是3秒,不会低于这个值,对于大部分应用来说可以接受,但是对于小部分应用需要优化。

查看一个设置访问mysql超时的php实例:

复制代码 代码如下:

?php

//自己定义读写超时常量

if(!defined('MYSQL_OPT_READ_TIMEOUT')){

define('MYSQL_OPT_READ_TIMEOUT',11);

}

if(!defined('MYSQL_OPT_WRITE_TIMEOUT')){

define('MYSQL_OPT_WRITE_TIMEOUT',12);

}

//设置超时

$mysqli=mysqli_init();

$mysqli-options(MYSQL_OPT_READ_TIMEOUT,3);

$mysqli-options(MYSQL_OPT_WRITE_TIMEOUT,1);

//连接数据库

$mysqli-real_connect("localhost","root","root","test");

if(mysqli_connect_errno()){

printf("Connectfailed:%s/n",mysqli_connect_error());

exit();

}

//执行查询sleep1秒不超时

printf("Hostinformation:%s/n",$mysqli-host_info);

if(!($res=$mysqli-query('selectsleep(1)'))){

echo"query1error:".$mysqli-error."/n";

}else{

echo"Query1:querysuccess/n";

}

//执行查询sleep9秒会超时

if(!($res=$mysqli-query('selectsleep(9)'))){

echo"query2error:".$mysqli-error."/n";

}else{

echo"Query2:querysuccess/n";

}

$mysqli-close();

echo"closemysqlconnection/n";

?

延伸阅读:

【Memcached】

[PHP扩展]

php_memcache客户端:

连接超时:boolMemcache::connect(string$host[,int$port[,int$timeout]])

在get和set的时候,都没有明确的超时设置参数。

libmemcached客户端:在php接口没有明显的超时参数。

说明:所以说,在PHP中访问Memcached是存在很多问题的,需要自己hack部分操作,或者是参考网上补丁。

[CC++访问Memcached]

客户端:libmemcached客户端

说明:memcache超时配置可以配置小点,比如5,10个毫秒已经够用了,超过这个时间还不如从数据库查询。

下面是一个连接和读取set数据的超时的C++示例:

复制代码 代码如下:

//创建连接超时(连接到Memcached)

memcached_st*MemCacheProxy::_create_handle()

{

memcached_st*mmc=NULL;

memcached_return_tprc;

if(_mpool!=NULL){//getfrompool

mmc=memcached_pool_pop(_mpool,false,prc);

if(mmc==NULL){

__LOG_WARNING__("MemCacheProxy","gethandlefrompoolerror[%d]",(int)prc);

}

returnmmc;

}

memcached_st*handle=memcached_create(NULL);

if(handle==NULL){

__LOG_WARNING__("MemCacheProxy","create_handleerror");

returnNULL;

}

//设置连接/读取超时

memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_HASH,MEMCACHED_HASH_DEFAULT);

memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_NO_BLOCK,_noblock);//参数MEMCACHED_BEHAVIOR_NO_BLOCK为1使超时配置生效,不设置超时会不生效,关键时候会悲剧的,容易引起雪崩

memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,_connect_timeout);//连接超时

memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_RCV_TIMEOUT,_read_timeout);//读超时

memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_SND_TIMEOUT,_send_timeout);//写超时

memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_POLL_TIMEOUT,_poll_timeout);

//设置一致hash

//memcached_behavior_set_distribution(handle,MEMCACHED_DISTRIBUTION_CONSISTENT);

memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_DISTRIBUTION,MEMCACHED_DISTRIBUTION_CONSISTENT);

memcached_returnrc;

for(uinti=0;i_server_count;i++){

rc=memcached_server_add(handle,_ips[i],_ports[i]);

if(MEMCACHED_SUCCESS!=rc){

__LOG_WARNING__("MemCacheProxy","addserver[%s:%d]failed.",_ips[i],_ports[i]);

}

}

_mpool=memcached_pool_create(handle,_min_connect,_max_connect);

if(_mpool==NULL){

__LOG_WARNING__("MemCacheProxy","create_poolerror");

returnNULL;

}

mmc=memcached_pool_pop(_mpool,false,prc);

if(mmc==NULL){

__LOG_WARNING__("MyMemCacheProxy","gethandlefrompoolerror[%d]",(int)prc);

}

//__LOG_DEBUG__("MemCacheProxy","gethandle[%p]",handle);

returnmmc;

}

//设置一个key超时(set一个数据到memcached)

boolMemCacheProxy::_add(memcached_st*handle,unsignedint*key,constchar*value,intlen,unsignedinttimeout)

{

memcached_returnrc;

chartmp[1024];

snprintf(tmp,sizeof(tmp),"%u#%u",key[0],key[1]);

//有个timeout值

rc=memcached_set(handle,tmp,strlen(tmp),(char*)value,len,timeout,0);

if(MEMCACHED_SUCCESS!=rc){

returnfalse;

}

returntrue;

}

//Memcache读取数据超时(没有设置)

libmemcahed源码中接口定义:

LIBMEMCACHED_APIchar*memcached_get(memcached_st*ptr,constchar*key,size_tkey_length,size_t*value_length,uint32_t*flags,memcached_return_t*error);

LIBMEMCACHED_APImemcached_return_tmemcached_mget(memcached_st*ptr,constchar*const*keys,constsize_t*key_length,size_tnumber_of_keys);

从接口中可以看出在读取数据的时候,是没有超时设置的。

延伸阅读:

【如何实现超时】

程序中需要有超时这种功能,比如你单独访问一个后端Socket模块,Socket模块不属于我们上面描述的任何一种的时候,它的协议也是私有的,那么这个时候可能需要自己去实现一些超时处理策略,这个时候就需要一些处理代码了。

[PHP中超时实现]

一、初级:最简单的超时实现 (秒级超时)

思路很简单:链接一个后端,然后设置为非阻塞模式,如果没有连接上就一直循环,判断当前时间和超时时间之间的差异。

phpsocket中实现原始的超时:(每次循环都当前时间去减,性能会很差,cpu占用会较高)

复制代码 代码如下:

?

$host="127.0.0.1";

$port="80";

$timeout=15;//timeoutinseconds

$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)

ordie("Unabletocreatesocketn");

socket_set_nonblock($socket) //务必设置为阻塞模式

ordie("Unabletosetnonblockonsocketn");

$time=time();

//循环的时候每次都减去相应值

while(!@socket_connect($socket,$host,$port))//如果没有连接上就一直死循环

{

$err=socket_last_error($socket);

if($err==115||$err==114)

{

if((time()-$time)=$timeout)//每次都需要去判断一下是否超时了

{

socket_close($socket);

die("Connectiontimedout.n");

}

sleep(1);

continue;

}

die(socket_strerror($err)."n");

}

socket_set_block($this-socket)//还原阻塞模式

ordie("Unabletosetblockonsocketn");

?

二、升级:使用PHP自带异步IO去实现(毫秒级超时)

说明:

异步IO:异步IO的概念和同步IO相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。异步IO将比特分成小组进行传送,小组可以是8位的1个字符或更长。发送方可以在任何时刻发送这些比特组,而接收方从不知道它们会在什么时候到达。

多路复用:复用模型是对多个IO操作进行检测,返回可操作集合,这样就可以对其进行操作了。这样就避免了阻塞IO不能随时处理各个IO和非阻塞占用系统资源的确定。

使用socket_select()实现超时

socket_select(...,floor($timeout),ceil($timeout*1000000));

select的特点:能够设置到微秒级别的超时!

使用socket_select()的超时代码(需要了解一些异步IO编程的知识去理解)

复制代码 代码如下:

编程 调用类 编程#

?php

$server=newServer;

$client=newClient;

for(;;){

foreach($select-can_read(0)as$socket){

if($socket==$client-socket){

//NewClientSocket

$select-add(socket_accept($client-socket));

}

else{

//there'ssomethingtoreadon$socket

}

}

}

?

编程 异步多路复用IO 超时连接处理类 编程

?php

classselect{

var$sockets;

functionselect($sockets){

$this-sockets=array();

foreach($socketsas$socket){

$this-add($socket);

}

}

functionadd($add_socket){

array_push($this-sockets,$add_socket);

}

functionremove($remove_socket){

$sockets=array();

foreach($this-socketsas$socket){

if($remove_socket!=$socket)

$sockets[]=$socket;

}

$this-sockets=$sockets;

}

functioncan_read($timeout){

$read=$this-sockets;

socket_select($read,$write=NULL,$except=NULL,$timeout);

return$read;

}

functioncan_write($timeout){

$write=$this-sockets;

socket_select($read=NULL,$write,$except=NULL,$timeout);

return$write;

}

}

?

[CC++中超时实现]

一般在LinuxC/C++中,可以使用:alarm()设置定时器的方式实现秒级超时,或者:select()、poll()、epoll()之类的异步复用IO实现毫秒级超时。也可以使用二次封装的异步io库(libevent,libev)也能实现。

一、使用alarm中用信号实现超时 (秒级超时)

说明:Linux内核connect超时通常为75秒,我们可以设置更小的时间如10秒来提前从connect中返回。这里用使用信号处理机制,调用alarm,超时后产生SIGALRM信号(也可使用select实现)

用alarym秒级实现 connect设置超时代码示例:

复制代码 代码如下:

//信号处理函数

staticvoidconnect_alarm(intsigno)

{

debug_printf("SignalHandler");

return;

}

//alarm超时连接实现

staticvoidconn_alarm()

{

Sigfunc*sigfunc;//现有信号处理函数

sigfunc=signal(SIGALRM,connect_alarm);//建立信号处理函数connect_alarm,(如果有)保存现有的信号处理函数

inttimeout=5;

//设置闹钟

if(alarm(timeout)!=0){

//...闹钟已经设置处理

}

//进行连接操作

if(connect(m_Socket,(structsockaddr*)addr,sizeof(addr))0){

if(errno==EINTR){//如果错误号设置为EINTR,说明超时中断了

debug_printf("Timeout");

怎样让phpstorm支持Yii2的Behavior中的方法

打开phpstorm8的界面,点击File--settings 如下图 点击完成后,显示的界面如下图 也可以直接使用快捷键ctrl+alt+s打开如下界面 点击Appearance Behavior---keymap 显示的界面如下所示 也可以在搜索框中输入keymap 直接打开设置界面 在上图中我...

php中多维数组的问题

"Griffin"=array()

表示索引"Griffin"是一个数组。=可以简单理解为赋值。这是php里特有的一种写法。

数组分为2种,一种是自动索引数组。比如

$x=array ("Peter","Lois", "Megan");

那么$X[0]值为"peter",$X[1]为lois。

还有一种是自定义索引数组。

比如

$x=array ("father"="Peter","mother"="Lois","son"= "Megan");

那么$x["father"] 就为"peter"

用引号围起来表示这是一个索引字符串值。通常情况下你直接[Griffin]也可以。

但是如果你在系统里有一个变量

$Griffin="son";

那么$families[Griffin]实际上会等于$families['son']。所以最好用引号围起来。

更多详细可以看php手册数组一章。

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

数组

PHP 中的 数组 实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字典,集合,栈,队列以及更多可能性。数组元素的值也可以是另一个数组。树形结构和多维数组也是允许的。

解释这些结构超出了本手册的范围,但对于每种结构至少会提供一个例子。要得到这些结构的更多信息,建议参考有关此广阔主题的其它著作。

语法

定义数组 array()

可以用 array() 语言结构来新建一个 array。它接受任意数量用逗号分隔的 键(key) = 值(value) 对。

array( key = value

, ...

)

// 键(key) 可是是一个 整数(integer) 或 字符串(string)

// 值(value) 可以是任意类型的值?php

$arr = array("foo" = "bar", 12 = true);

echo $arr["foo"]; // bar

echo $arr[12]; // 1

?

key 可以是 integer 或者 string。如果key是一个 integer 的标准表示,则被解释为整数(例如 "8" 将被解释为 8,而 "08" 将被解释为 "08")。key 中的浮点数被取整为 integer。在 PHP 中索引数组与关联 数组 是相同的,它们都可以同时包含 整型 和 字符串 的下标。

值可以是任意的 PHP 类型。

?php

$arr = array("somearray" = array(6 = 5, 13 = 9, "a" = 42));

echo $arr["somearray"][6]; // 5

echo $arr["somearray"][13]; // 9

echo $arr["somearray"]["a"]; // 42

?

如果对给出的值没有指定键名,则取当前最大的整数索引值,而新的键名将是该值加一。如果指定的键名已经有了值,则该值会被覆盖。

?php

// 这个数组与下面的数组相同 ...

array(5 = 43, 32, 56, "b" = 12);

// ...

array(5 = 43, 6 = 32, 7 = 56, "b" = 12);

?

Warning

自 PHP 4.3.0 起,上述的索引生成方法改变了。如今如果给一个当前最大键名是负值的数组添加一个新值,则新生成的的索引将为零(0)。以前新生成的索引为当前最大索引加一,和正值的索引相同。

使用 TRUE 作为键名将使 integer 1 成为键名。使用 FALSE 作为键名将使 integer 0 成为键名。使用 NULL 作为键名将等同于使用空字符串。使用空字符串作为键名将新建(或覆盖)一个用空字符串作为键名的值,这和用空的方括号不一样。

不能用数组和对象作为键(key)。这样做会导致一个警告:Illegal offset type。

用方括号的语法新建/修改

可以通过明示地设定值来改变一个现有的数组。

这是通过在方括号内指定键名来给数组赋值实现的。也可以省略键名,在这种情况下给变量名加上一对空的方括号(“[]”)。

$arr[key] = value;

$arr[] = value;

// key 可以是 integer 或 string

// value 可以是任意类型的值如果 $arr 还不存在,将会新建一个。这也是一种定义数组的替换方法。要改变一个值,只要给它赋一个新值。如果要删除一个键名/值对,要对它用 unset()。

?php

$arr = array(5 = 1, 12 = 2);

$arr[] = 56; // This is the same as $arr[13] = 56;

// at this point of the script

$arr["x"] = 42; // This adds a new element to

// the array with key "x"

unset($arr[5]); // This removes the element from the array

unset($arr); // This deletes the whole array

?

Note:

如上所述,如果给出方括号但没有指定键名,则取当前最大整数索引值,新的键名将是该值 + 1。如果当前还没有整数索引,则键名将为 0。如果指定的键名已经有值了,该值将被覆盖。

注意这里所使用的最大整数键名不一定当前就在数组中。它只要在上次数组重新生成索引后曾经存在过就行了。以下面的例子来说明:

?php

// 创建一个简单的数组

$array = array(1, 2, 3, 4, 5);

print_r($array);

// 现在删除其中的所有元素,但保持数组本身不变:

foreach ($array as $i = $value) {

unset($array[$i]);

}

print_r($array);

// 添加一个单元(注意新的键名是 5,而不是你可能以为的 0)

$array[] = 6;

print_r($array);

// 重新索引:

$array = array_values($array);

$array[] = 7;

print_r($array);

?

以上例程会输出:

Array

(

[0] = 1

[1] = 2

[2] = 3

[3] = 4

[4] = 5

)

Array

(

)

Array

(

[5] = 6

)

Array

(

[0] = 6

[1] = 7

)

实用函数

有很多操作数组的函数,参见数组函数一节。

Note:

unset() 函数允许删除数组中的某个键。但要注意数组将不会重建索引。 If a true "remove and shift" behavior is desired, the array can be reindexed using the array_values() function.

?php

$a = array(1 = 'one', 2 = 'two', 3 = 'three');

unset($a[2]);

/* will produce an array that would have been defined as

$a = array(1 = 'one', 3 = 'three');

and NOT

$a = array(1 = 'one', 2 ='three');

*/

$b = array_values($a);

// Now $b is array(0 = 'one', 1 ='three')

?

foreach 控制结构是专门用于数组的。它提供了一个简单的方法来遍历数组。

数组做什么和不做什么

为什么 $foo[bar] 错了?

应该始终在用字符串表示的数组索引上加上引号。例如用 $foo['bar'] 而不是 $foo[bar]。但是为什么 $foo[bar] 错了呢?可能在老的脚本中见过如下语法:

?php

$foo[bar] = 'enemy';

echo $foo[bar];

// etc

?

这样是错的,但可以正常运行。那么为什么错了呢?原因是此代码中有一个未定义的常量(bar)而不是字符串('bar'-注意引号),而 PHP 可能会在以后定义此常量,不幸的是你的代码中有同样的名字。它能运行,是因为 PHP 自动将裸字符串(没有引号的字符串且不对应于任何已知符号)转换成一个其值为该裸字符串的正常字符串。例如,如果没有常量定义为 bar,PHP 将把它替代为 'bar' 并使用之。

Note: 这并不意味着总是给键名加上引号。用不着给键名为常量或变量的加上引号,否则会使 PHP 不能解析它们。

?php

error_reporting(E_ALL);

ini_set('display_errors', true);

ini_set('html_errors', false);

// Simple array:

$array = array(1, 2);

$count = count($array);

for ($i = 0; $i $count; $i++) {

echo "\nChecking $i: \n";

echo "Bad: " . $array['$i'] . "\n";

echo "Good: " . $array[$i] . "\n";

echo "Bad: {$array['$i']}\n";

echo "Good: {$array[$i]}\n";

}

?

以上例程会输出:

Checking 0:

Notice: Undefined index: $i in /path/to/script.html on line 9

Bad:

Good: 1

Notice: Undefined index: $i in /path/to/script.html on line 11

Bad:

Good: 1

Checking 1:

Notice: Undefined index: $i in /path/to/script.html on line 9

Bad:

Good: 2

Notice: Undefined index: $i in /path/to/script.html on line 11

Bad:

Good: 2

演示此行为的更多例子:

?php

// Show all errors

error_reporting(E_ALL);

$arr = array('fruit' = 'apple', 'veggie' = 'carrot');

// Correct

print $arr['fruit']; // apple

print $arr['veggie']; // carrot

// Incorrect. This works but also throws a PHP error of level E_NOTICE because

// of an undefined constant named fruit

//

// Notice: Use of undefined constant fruit - assumed 'fruit' in...

print $arr[fruit]; // apple

// This defines a constant to demonstrate what's going on. The value 'veggie'

// is assigned to a constant named fruit.

define('fruit', 'veggie');

// Notice the difference now

print $arr['fruit']; // apple

print $arr[fruit]; // carrot

// The following is okay, as it's inside a string. Constants are not looked for

// within strings, so no E_NOTICE occurs here

print "Hello $arr[fruit]"; // Hello apple

// With one exception: braces surrounding arrays within strings allows constants

// to be interpreted

print "Hello {$arr[fruit]}"; // Hello carrot

print "Hello {$arr['fruit']}"; // Hello apple

// This will not work, and will result in a parse error, such as:

// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'

// This of course applies to using superglobals in strings as well

print "Hello $arr['fruit']";

print "Hello $_GET['foo']";

// Concatenation is another option

print "Hello " . $arr['fruit']; // Hello apple

?

当打开 error_reporting 来显示 E_NOTICE 级别的错误(例如将其设为 E_ALL)时将看到这些错误。默认情况下 error_reporting 被关闭不显示这些。

和在语法一节中规定的一样,在方括号(“[”和“]”)之间必须有一个表达式。这意味着可以这样写:

?php

echo $arr[somefunc($bar)];

?

这是一个用函数返回值作为数组索引的例子。PHP 也可以用已知常量,可能之前已经见过

?php

$error_descriptions[E_ERROR] = "A fatal error has occured";

$error_descriptions[E_WARNING] = "PHP issued a warning";

$error_descriptions[E_NOTICE] = "This is just an informal notice";

?

注意 E_ERROR 也是个合法的标识符,就和第一个例子中的 bar 一样。但是上一个例子实际上和如下写法是一样的:

?php

$error_descriptions[1] = "A fatal error has occured";

$error_descriptions[2] = "PHP issued a warning";

$error_descriptions[8] = "This is just an informal notice";

?

因为 E_ERROR 等于 1, 等等.

那么为什么这样做不好?

也许有一天,PHP 开发小组可能会想新增一个常量或者关键字,或者用户可能希望以后在自己的程序中引入新的常量,那就有麻烦了。例如已经不能这样用 empty 和 default 这两个词了,因为他们是保留字。

Note: 重申一次,在双引号字符串中,不给索引加上引号是合法的因此 "$foo[bar]"是合法的(“合法”的原文为valid。在实际测试中,这么做确实可以访问数组的该元素,但是会报一个常量未定义的notice。无论如何,强烈建议不要使用$foo[bar]这样的写法,而要使用$foo['bar']来访问数组中元素。--haohappy注)。至于为什么参见以上的例子和字符串中的变量解析中的解释。

转换为数组

对于任意类型: integer, float, string, boolean and resource,如果将一个值转换为数组,将得到一个仅有一个元素的数组(其下标为 0),该元素即为此标量的值。换句话说, (array)$scalarValue 与 array($scalarValue) 完全一样。

If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour:

?php

class A {

private $A; // This will become '\0A\0A'

}

class B extends A {

private $A; // This will become '\0B\0A'

public $AA; // This will become 'AA'

}

var_dump((array) new B());

?

The above will appear to have two keys named 'AA', although one of them is actually named '\0A\0A'.

将 NULL 转换到 数组(array) 会得到一个空的数组。

比较

可能使用 array_diff() 和数组运算符来比较数组。

Examples

PHP 中的数组类型有非常多的用途,因此这里有一些例子展示数组的完整威力。

?php

// This:

$a = array( 'color' = 'red',

'taste' = 'sweet',

'shape' = 'round',

'name' = 'apple',

4 // key will be 0

);

$b = array('a', 'b', 'c');

// . . .is completely equivalent with this:

$a = array();

$a['color'] = 'red';

$a['taste'] = 'sweet';

$a['shape'] = 'round';

$a['name'] = 'apple';

$a[] = 4; // key will be 0

$b = array();

$b[] = 'a';

$b[] = 'b';

$b[] = 'c';

// After the above code is executed, $a will be the array

// array('color' = 'red', 'taste' = 'sweet', 'shape' = 'round',

// 'name' = 'apple', 0 = 4), and $b will be the array

// array(0 = 'a', 1 = 'b', 2 = 'c'), or simply array('a', 'b', 'c').

?

Example #1 Using array()

?php

// Array as (property-)map

$map = array( 'version' = 4,

'OS' = 'Linux',

'lang' = 'english',

'short_tags' = true

);

// strictly numerical keys

$array = array( 7,

8,

0,

156,

-10

);

// this is the same as array(0 = 7, 1 = 8, ...)

$switching = array( 10, // key = 0

5 = 6,

3 = 7,

'a' = 4,

11, // key = 6 (maximum of integer-indices was 5)

'8' = 2, // key = 8 (integer!)

'02' = 77, // key = '02'

0 = 12 // the value 10 will be overwritten by 12

);

// empty array

$empty = array();

?

Example #2 集合

?php

$colors = array('red', 'blue', 'green', 'yellow');

foreach ($colors as $color) {

echo "Do you like $color?\n";

}

?

以上例程会输出:

Do you like red?

Do you like blue?

Do you like green?

Do you like yellow?

直接改变数组的值在 PHP 5 中可以通过引用传递来做到。之前的版本需要需要采取变通的方法:

Example #3 集合

?php

// PHP 5

foreach ($colors as $color) {

$color = strtoupper($color);

}

unset($color); /* ensure that following writes to

$color will not modify the last array element */

// Workaround for older versions

foreach ($colors as $key = $color) {

$colors[$key] = strtoupper($color);

}

print_r($colors);

?

以上例程会输出:

Array

(

[0] = RED

[1] = BLUE

[2] = GREEN

[3] = YELLOW

)

本例生成一个下标从1开始的数组。This example creates a one-based array.

Example #4 下标从1开始的数组

?php

$firstquarter = array(1 = 'January', 'February', 'March');

print_r($firstquarter);

?

以上例程会输出:

Array

(

[1] = 'January'

[2] = 'February'

[3] = 'March'

)

Example #5 填充数组

?php

// fill an array with all items from a directory

$handle = opendir('.');

while (false !== ($file = readdir($handle))) {

$files[] = $file;

}

closedir($handle);

?

数组是有序的。也可以使用不同的排序函数来改变顺序。更多信息参见数组函数。可以用 count() 函数来数出数组中元素的个数。

Example #6 数组排序

?php

sort($files);

print_r($files);

?

因为数组中的值可以为任意值,也可是另一个数组。这样可以产生递归或多维数组。

Example #7 递归和多维数组

?php

$fruits = array ( "fruits" = array ( "a" = "orange",

"b" = "banana",

"c" = "apple"

),

"numbers" = array ( 1,

2,

3,

4,

5,

6

),

"holes" = array ( "first",

5 = "second",

"third"

)

);

// Some examples to address values in the array above

echo $fruits["holes"][5]; // prints "second"

echo $fruits["fruits"]["a"]; // prints "orange"

unset($fruits["holes"][0]); // remove "first"

// Create a new multi-dimensional array

$juices["apple"]["green"] = "good";

?

数组(Array) 的赋值总是会涉及到值的拷贝。使用 引用操作符 通过引用来拷贝数组。

?php

$arr1 = array(2, 3);

$arr2 = $arr1;

$arr2[] = 4; // $arr2 is changed,

// $arr1 is still array(2, 3)

$arr3 = $arr1;

$arr3[] = 4; // now $arr1 and $arr3 are the same

?

关于behaviorphp和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

发布于 2023-04-09 16:04:15
收藏
分享
海报
31
目录

    忘记密码?

    图形验证码

    复制成功
    微信号: cloud7591
    如需了解更多,欢迎添加客服微信咨询。
    我知道了