首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
183 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
31
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-08-08
PHP中的Memcache详解
PHP中的Memcache详解这篇文章主要介绍了PHP中的Memcache,从Memcache简介开始,详细讲解了如Memcache和memcached的区别、PHP的Memcache所有操作方法、每个操作方法的详细解释等,需要的朋友可以参考下一、Memcache简介Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached管理这些HashTable,所以速度非常快。 二、Memcache和memcached的区别为什么会有Memcache和memcached两种名称?其实Memcache是这个项目的名称,而memcached是它服务器端的主程序文件名,知道我的意思了把~~~~。一个是项目名称,一个是主程序文件名,在网上看到了很多人不明白,于是混用了。三、Memcache的服务器端和客户端安装分为两个过程:memcache服务器端的安装和memcached客户端的安装。所谓服务器端的安装就是在服务器(一般都是linux系统)上安装Memcache实现数据的存储。所谓客户端的安装就是指php(或者其他程序,Memcache还有其他不错的api接口提供)去使用服务器端的Memcache提供的函数,需要php添加扩展。四、PHP的Memcache客户端所有方法总结memcache函数所有的方法列表如下:Memcache::add – 添加一个值,如果已经存在,则返回falseMemcache::addServer – 添加一个可供使用的服务器地址Memcache::close – 关闭一个Memcache对象Memcache::connect – 创建一个Memcache对象memcache_debug – 控制调试功能Memcache::decrement – 对保存的某个key中的值进行减法操作Memcache::delete – 删除一个key值Memcache::flush – 清除所有缓存的数据Memcache::get – 获取一个key值Memcache::getExtendedStats – 获取进程池中所有进程的运行系统统计Memcache::getServerStatus – 获取运行服务器的参数Memcache::getStats – 返回服务器的一些运行统计信息Memcache::getVersion – 返回运行的Memcache的版本信息Memcache::increment – 对保存的某个key中的值进行加法操作Memcache::pconnect – 创建一个Memcache的持久连接对象Memcache::replace -对一个已有的key进行覆写操作Memcache::set – 添加一个值,如果已经存在,则覆写Memcache::setCompressThreshold – 对大于某一大小的数据进行压缩Memcache::setServerParams – 在运行时修改服务器的参数五、PHP的Memcache操作方法分解Memcache::add用法复制代码代码如下:bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] )说明:如果$key不存在的时候,使用这个函数来存储$var的值。功能相同的函数是memcache_add()。参数:$key :将要存储的键值。$var :存储的值,字符型和整型会按原值保存,其他类型自动序列化以后保存。$flag:是否用MEMCACHE_COMPRESSED来压缩存储的值,true表示压缩,false表示不压缩。$expire:存储值的过期时间,如果为0表示不会过期,你可以用unix时间戳或者描述来表示从现在开始的时间,但是你在使用秒数表示的时候,不要超过2592000秒 (表示30天)。返回值:如果成功则返回 TRUE,失败则返回 FALSE。如果$key值已经存在,则会返回FALSE。 其他情况下Memcache::add()的用法类似于Memcache::set()。例子:复制代码代码如下:<?php$memcache_obj = memcache_connect(”localhost”, 11211);memcache_add($memcache_obj, 'var_key', 'test variable', false, 30);$memcache_obj->add('var_key', 'test variable', false, 30);?>Memcache::addServer用法复制代码代码如下:bool Memcache::addServer ( string $host [, int $port [, bool $persistent [, int $weight [, int$timeout [, int $retry_interval [, bool $status [, callback $failure_callback ]]]]]]] )说明:添加一个可供使用的服务器地址到连接池中,连接用Memcache::addServer打开,脚本执行完后自动关闭,或者可以用Memcache::close()手动关闭。相同函数是memcache_add_server()。当用这个方法的时候(相对于Memcache::connect()和 Memcache::pconnect()方法),网络连接只有等需要的时候才会建立,因此不会因为增加很多的服务器到连接池而增加系统负担,因为很多服务器可能没有使用。故障恢复会发生在这个方法执行的任何阶段,只要其他的服务器是正常的,这些连接请求的失败用户不会注意到。任何一种socket或者memcached服务器级的错误可以触发故障恢复。正常的客户端错误比如增加一个存在的键值不会引发故障恢复。参数:$host服务器的地址$port服务器端口$persistent是否是一个持久连接$weight这台服务器在所有服务器中所占的权重$timeout连接的持续时间$retry_interval连接重试的间隔时间,默认为15,设置为-1表示不进行重试$status控制服务器的在线状态$failure_callback允许设置一个回掉函数来处理错误信息。返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:<?php$memcache = new Memcache;$memcache->addServer('memcache_host', 11211);$memcache->addServer('memcache_host2′, 11211);$memcache_obj = memcache_connect('memcache_host', 11211);memcache_add_server($memcache_obj, 'memcache_host2′, 11211);?>Memcache::close用法bool Memcache::close ( void )说明:关闭memcache服务器连接。这个函数不会关闭长连接,长连接只有在web服务器关闭或者重启的时候才会关闭。相同的函数memcache_close()返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:<?php$memcache_obj = memcache_connect('memcache_host', 11211);memcache_close($memcache_obj);$memcache_obj = new Memcache;$memcache_obj->connect('memcache_host', 11211);$memcache_obj->close();?>Memcache::connect用法复制代码代码如下:bool Memcache::connect ( string $host [, int $port [, int $timeout ]] )说明:打开memcached服务器连接,建立一个到memcached服务器的连接,用Memcache::connect打开的连接会在脚本执行完毕后自动关闭。你也可以用Memcache::close()去关闭连接。相同的函数是memcache_connect()。参数:$host:指向memcached正在收听的链接的主机,这个参数会有另一种特殊的连接方式unix:///path/to/memcached.sock,即用unix的域名sockets,这种情况下,端口必须设置为0$port:指向memcached正在收听的链接的端口,用unix的域名sockets的情况下,端口必须设置为0$timeout:用于连接守护进程的秒数,当你改变默认的1秒的值的时候,你需要考虑一下,如果你的连接太慢的话,你可能会失去缓存的优势。返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:<?php$memcache_obj = memcache_connect('memcache_host', 11211);$memcache = new Memcache;$memcache->connect('memcache_host', 11211);?>memcache::debug复制代码代码如下:bool memcache_debug ( bool $on_off )说明:控制调试功能,前提是php在编译的时候使用了-enable-debug选项,否则这个函数不会有作用。参数:$on_off:true表示开启调试,false表示关闭调试返回值:如果php在编译的时候使用了-enable-debug选项,返回true,否则返回falseMemcache::decrement用法复制代码代码如下:int Memcache::decrement ( string $key [, int $value ] )说明:Memcache::decremen方法的作用是对保存的某个key中的值进行减法操作,用法跟Memcache::increment类似。你也可以用memcache_decrement()函数。参数:Key:想要减少的键的名字Value:想要减少的值。返回值:如果成功,返回被减少后的值,如果失败返回false。例子:复制代码代码如下:<?php$memcache = new Memcache;$memcache->connect('localhost', 11211);$memcache->set('test_item', 8);$memcache->increment('test_item', 4);echo $memcache->decrement('test_item', 7);// 显示 5?>这个例子连Memcache::increment函数都一块演示了。Memcache::delete用法复制代码代码如下:bool Memcache::delete ( string $key [, int $timeout ] )说明:删除一个key值,如果参数$timeout被设置,那么存储的值会在设置的秒数以后过期,你也可以用函数memcache_delete()返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:<?php$memcache_obj = memcache_connect('memcache_host', 11211);memcache_delete($memcache_obj, 'key_to_delete', 10);$memcache_obj = new Memcache;$memcache_obj->connect('memcache_host', 11211);$memcache_obj->delete('key_to_delete', 10);?>Memcache::flush复制代码代码如下:bool Memcache::flush ( void )说明:清除所有缓存的数据。Memcache::flush实际上没有释放资源,它仅仅将所有的缓存标记为过期,这样可以使新的缓存来覆盖被占的内存空间。一样的函数是memcache_flush()返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:<?php$memcache_obj = memcache_connect('memcache_host', 11211);memcache_flush($memcache_obj);$memcache_obj = new Memcache;$memcache_obj->connect('memcache_host', 11211);$memcache_obj->flush();?>Memcache::get复制代码代码如下:string Memcache::get ( string $key [, int &$flags ] )array Memcache::get ( array $keys [, array &$flags ] )说明:方法的作用是获取一个key值,key值可以是一个数组,结果会包含键值对。参数:$key是键值或者一个键的数组值。$flags如果这个参数存在,那么$flags跟写入这个参数的值相关,这些$flags 类似于Memcache::set()函数里的$flags。返回值:如果成功,则返回key对应的值,如果失败则返回false.例子:复制代码代码如下:<?php$memcache_obj = memcache_connect('memcache_host', 11211);$var = memcache_get($memcache_obj, 'some_key');$memcache_obj = new Memcache;$memcache_obj->connect('memcache_host', 11211);$var = $memcache_obj->get('some_key');$memcache_obj = memcache_connect('memcache_host', 11211);$var = memcache_get($memcache_obj, Array('some_key', 'another_key'));$memcache_obj = new Memcache;$memcache_obj->connect('memcache_host', 11211);$var = $memcache_obj->get(Array('some_key', 'second_key'));?>Memcache::getExtendedStats复制代码代码如下:array Memcache::getExtendedStats ([ string $type [, int $slabid [, int $limit ]]] )说明:获取进程池中所有进程的运行系统统计。相同函数是memcache_get_extended_stats()参数:$type表示要求返回的类型:reset, malloc, maps, cachedump, slabs, items, sizes;$slabid第一个参数设置为”cachedump”时使用的。$limit第一个参数设置为”cachedump”时使用的。返回值:如果成功,返回统计信息,失败会返回false例子:复制代码代码如下:<?php$memcache_obj = new Memcache;$memcache_obj->addServer('memcache_host', 11211);$memcache_obj->addServer('failed_host', 11211);$stats = $memcache_obj->getExtendedStats();//slabs机制分配管理内存的情况$statsslab = $memcache_obj->getExtendedStats(slabs);?>Memcache::getServerStatus复制代码代码如下:int Memcache::getServerStatus ( string $host [, int $port ] )说明:获取运行服务器的参数。返回一个服务器在线或者离线的状态。相同的函数是memcache_get_server_status()参数:$host:正在收听的连接的主机$port正在收听的连接的主机的端口,默认是11211返回值:成功返回服务器状态,服务器没有启动会返回0,其他数字的时候表示服务器是启动状态的。例子:复制代码代码如下:<?php$memcache = new Memcache;$memcache->addServer('memcache_host', 11211);echo $memcache->getServerStatus('memcache_host', 11211);$memcache = memcache_connect('memcache_host', 11211);echo memcache_get_server_status($memcache, 'memcache_host', 11211);?>Memcache::getStats复制代码代码如下:array Memcache::getStats ([ string $type [, int $slabid [, int $limit ]]] )说明:返回服务器的一些运行统计信息。相同的函数是memcache_get_stats()参数:$type表示要求返回的类型:reset, malloc, maps, cachedump, slabs, items, sizes;$slabid第一个参数设置为”cachedump”时使用的。$limit第一个参数设置为”cachedump”时使用的。Memcache::getVersion复制代码代码如下:string Memcache::getVersion ( void )说明:返回运行的Memcache的版本信息。相同函数memcache_get_version()返回值:成功返回服务器的版本信息,失败的时候返回false。例子:复制代码代码如下:<?php$memcache = new Memcache;$memcache->connect('memcache_host', 11211);echo $memcache->getVersion();$memcache = memcache_connect('memcache_host', 11211);echo memcache_get_version($memcache);?>Memcache::increment复制代码代码如下:int Memcache::increment ( string $key [, int $value ] )对保存的某个key中的值进行加法操作用法参考Memcache::decrementMemcache::pconnect复制代码代码如下:bool Memcache::pconnect ( string $host [, int $port [, int $timeout ]] )说明:创建一个Memcache的持久连接对象用法与Memcache::connect()相似,不同点地方是Memcache::pconnect是建立的持久连接。这个连接在脚本执行完或者Memcache::close()函数运行也不会被关闭。与它相同的函数是memcache_pconnect()参数:$host:指向memcached正在收听的链接的主机,这个参数会有另一种特殊的连接方式unix:///path/to/memcached.sock,即用unix的域名sockets,这种情况下,端口必须设置为0$port:指向memcached正在收听的链接的端口,用unix的域名sockets的情况下,端口必须设置为0$timeout:用于连接守护进程的秒数,当你改变默认的1秒的值的时候,你需要考虑一下,如果你的连接太慢的话,你可能会失去缓存的优势。返回值:如果成功则返回 TRUE,失败则返回 FALSE复制代码代码如下:<?php$memcache_obj = memcache_pconnect('memcache_host', 11211);$memcache_obj = new Memcache;$memcache_obj->pconnect('memcache_host', 11211);?>Memcache::replace复制代码代码如下:bool Memcache::replace ( string $key , mixed $var [, int $flag [, int $expire ]] )说明:对一个已有的key进行覆写操作。相同函数是memcache_replace()参数:$key :将要存储的键值。$var :存储的值,字符型和整型会按原值保存,其他类型自动序列化以后保存。$flag:是否用MEMCACHE_COMPRESSED来压缩存储的值,true表示压缩,false表示不压缩。$expire:存储值的过期时间,如果为0表示不会过期,你可以用unix时间戳或者描述来表示从现在开始的时间,但是你在使用秒数表示的时候,不要超过2592000秒 (表示30天)。返回值:如果成功则返回 TRUE,失败则返回 FALSE。如果$key值已经存在,则会返回FALSE。复制代码代码如下:<?php$memcache_obj = memcache_connect('memcache_host', 11211);memcache_replace($memcache_obj, "test_key", "some variable", false, 30);$memcache_obj->replace("test_key", "some variable", false, 30);?>Memcache::set复制代码代码如下:bool Memcache::set ( string $key , mixed $var [, int $flag [, int $expire ]] )说明:添加一个值,如果已经存在,则覆写。相同函数是memcache_set()参数:$key :将要存储的键值。$var :存储的值,字符型和整型会按原值保存,其他类型自动序列化以后保存。$flag:是否用MEMCACHE_COMPRESSED来压缩存储的值,true表示压缩,false表示不压缩。$expire:存储值的过期时间,如果为0表示不会过期,你可以用unix时间戳或者描述来表示从现在开始的时间,但是你在使用秒数表示的时候,不要超过2592000秒 (表示30天)。返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:$memcache_obj = new Memcache;$memcache_obj->connect('memcache_host', 11211);$memcache_obj->set('var_key', 'some really big variable', MEMCACHE_COMPRESSED, 50);echo $memcache_obj->get('var_key');Memcache::setCompressThreshold复制代码代码如下:bool Memcache::setCompressThreshold ( int $threshold [, float $min_savings ] )说明:对大于某一大小的数据进行压缩。相同的函数是memcache_set_compress_threshold()参数:setCompressThreshold方法有两个参数,第一个参数表示处理数据大小的临界点,第二个参数表示压缩的比例,默认为0.2。返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:<?php$memcache_obj = new Memcache;$memcache_obj->addServer('memcache_host', 11211);$memcache_obj->setCompressThreshold(20000, 0.2);$memcache_obj = memcache_connect('memcache_host', 11211);memcache_set_compress_threshold($memcache_obj, 20000, 0.2);?>Memcache::setServerParams复制代码代码如下:bool Memcache::setServerParams ( string $host [, int $port [, int $timeout [, int$retry_interval [, bool $status [, callback $failure_callback ]]]]] )说明:在运行时修改服务器的参数。相同函数是memcache_set_server_params()。参数:$host服务器的地址$port服务器端口$timeout连接的持续时间$retry_interval连接重试的间隔时间,默认为15,设置为-1表示不进行重试$status控制服务器的在线状态$failure_callback允许设置一个回掉函数来处理错误信息。返回值:如果成功则返回 TRUE,失败则返回 FALSE。例子:复制代码代码如下:<?phpfunction _callback_memcache_failure($host, $port) {print "memcache '$host:$port' failed";}$memcache = new Memcache;// 离线模式增加一个服务器$memcache->addServer('memcache_host', 11211, false, 1, 1, -1, false);// 把服务器设成在线$memcache->setServerParams('memcache_host', 11211, 1, 15, true, '_callback_memcache_failure');$memcache_obj = memcache_connect('memcache_host', 11211);memcache_set_server_params($memcache_obj, 'memcache_host', 11211, 1, 15, true, '_callback_memcache_failure');?>六、综合使用实例复制代码代码如下:<?php//连接$mem = new Memcache;$mem->connect("db.nowamagic.net", 12000);//保存数据$mem->set('key1', 'This is first value', 0, 60);$val = $mem->get('key1');echo "Get key1 value: " . $val ."";//替换数据$mem->replace('key1', 'This is replace value', 0, 60);$val = $mem->get('key1');echo "Get key1 value: " . $val . "";//保存数组$arr = array('aaa', 'bbb', 'ccc', 'ddd');$mem->set('key2', $arr, 0, 60);$val2 = $mem->get('key2');echo "Get key2 value: ";print_r($val2);echo "";//删除数据$mem->delete('key1');$val = $mem->get('key1');echo "Get key1 value: " . $val . "";//清除所有数据$mem->flush();$val2 = $mem->get('key2');echo "Get key2 value: ";print_r($val2);echo "";//关闭连接$mem->close();?>如果正常的话,浏览器将输出:复制代码代码如下:Get key1 value: This is first valueGet key1 value: This is replace valueGet key2 value: Array ( [0] => aaa [1] => bbb [2] => ccc [3] => ddd )Get key1 value:Get key2 value:七、实例程序代码分析初始化一个Memcache的对象:$mem = new Memcache;连接到我们的Memcache服务器端,第一个参数是服务器的IP地址,也可以是主机名,第二个参数是Memcache的开放的端口:$mem->connect("192.168.0.200", 12000);保存一个数据到Memcache服务器上,第一个参数是数据的key,用来定位一个数据,第二个参数是需要保存的数据内容,这里是一个字符串,第三个参数是一个标记,一般设置为0或者MEMCACHE_COMPRESSED就行了,第四个参数是数据的有效期,就是说数据在这个时间内是有效的,如果过去这个时间,那么会被Memcache服务器端清除掉这个数据,单位是秒,如果设置为0,则是永远有效,我们这里设置了60,就是一分钟有效时间:$mem->set(‘key1‘, ‘This is first value', 0, 60);从Memcache服务器端获取一条数据,它只有一个参数,就是需要获取数据的key,我们这里是上一步设置的key1,现在获取这个数据后输出输出:复制代码代码如下:$val = $mem->get('key1′);echo "Get key1 value: " . $val;现在是使用replace方法来替换掉上面key1的值,replace方法的参数跟set是一样的,不过第一个参数key1是必须是要替换数据内容的key,最后输出了:复制代码代码如下:$mem->replace('key1', 'This is replace value', 0, 60);$val = $mem->get('key1');echo "Get key1 value: " . $val;同样的,Memcache也是可以保存数组的,下面是在Memcache上面保存了一个数组,然后获取回来并输出:复制代码代码如下:$arr = array('aaa', 'bbb', 'ccc', 'ddd');$mem->set('key2', $arr, 0, 60);$val2 = $mem->get('key2');print_r($val2);现在删除一个数据,使用delte接口,参数就是一个key,然后就能够把Memcache服务器这个key的数据删除,最后输出的时候没有结果:复制代码代码如下:$mem->delete('key1');$val = $mem->get('key1');echo "Get key1 value: " . $val . "";最后我们把所有的保存在Memcache服务器上的数据都清除,会发现数据都没有了,最后输出key2的数据为空,最后关闭连接:复制代码代码如下:$mem->flush();$val2 = $mem->get('key2');echo "Get key2 value: ";print_r($val2);echo "";八、什么时候使用Memcache和Memcache的使用环境使用Memcache的网站一般流量都是比较大的,为了缓解数据库的压力,让Memcache作为一个缓存区域,把部分信息保存在内存中,在前端能够迅速的进行存取。那么一般的焦点就是集中在如何分担数据库压力和进行分布式,毕竟单台Memcache的内存容量的有限的。我这里简单提出我的个人看法,未经实践,权当参考。分布式应用Memcache本来支持分布式,我们客户端稍加改造,更好的支持。我们的key可以适当进行有规律的封装,比如以user为主的网站来说,每个用户都有User ID,那么可以按照固定的ID来进行提取和存取,比如1开头的用户保存在第一台Memcache服务器上,以2开头的用户的数据保存在第二胎Mecache服务器上,存取数据都先按照User ID来进行相应的转换和存取。但是这个有缺点,就是需要对User ID进行判断,如果业务不一致,或者其他类型的应用,可能不是那么合适,那么可以根据自己的实际业务来进行考虑,或者去想更合适的方法。减少数据库压力这个算是比较重要的,所有的数据基本上都是保存在数据库当中的,每次频繁的存取数据库,导致数据库性能极具下降,无法同时服务更多的用户,比如MySQL,特别频繁的锁表,那么让Memcache来分担数据库的压力吧。我们需要一种改动比较小,并且能够不会大规模改变前端的方式来进行改变目前的架构。我考虑的一种简单方法:后端的数据库操作模块,把所有的Select操作提取出来(update/delete/insert不管),然后把对应的SQL进行相应的hash算法计算得出一个hash数据key(比如MD5或者SHA),然后把这个key去Memcache中查找数据,如果这个数据不存在,说明还没写入到缓存中,那么从数据库把数据提取出来,一个是数组类格式,然后把数据在set到Memcache中,key就是这个SQL的hash值,然后相应的设置一个失效时间,比如一个小时,那么一个小时中的数据都是从缓存中提取的,有效减少数据库的压力。缺点是数据不实时,当数据做了修改以后,无法实时到前端显示,并且还有可能对内存占用比较大,毕竟每次select出来的数据数量可能比较巨大,这个是需要考虑的因素。九、Memcache的安全我们上面的Memcache服务器端都是直接通过客户端连接后直接操作,没有任何的验证过程,这样如果服务器是直接暴露在互联网上的话是比较危险,轻则数据泄露被其他无关人员查看,重则服务器被入侵,因为Mecache是以root权限运行的,况且里面可能存在一些我们未知的bug或者是缓冲区溢出的情况,这些都是我们未知的,所以危险性是可以预见的。为了安全起见,我做两点建议,能够稍微的防止黑客的入侵或者数据的泄露。内网访问最好把两台服务器之间的访问是内网形态的,一般是Web服务器跟Memcache服务器之间。普遍的服务器都是有两块网卡,一块指向互联网,一块指向内网,那么就让Web服务器通过内网的网卡来访问Memcache服务器,我们Memcache的服务器上启动的时候就监听内网的IP地址和端口,内网间的访问能够有效阻止其他非法的访问。复制代码代码如下:memcached -d -m 1024 -u root -l 192.168.0.200 -p 11211 -c 1024 -P /tmp/memcached.pidMemcache服务器端设置监听通过内网的192.168.0.200的ip的11211端口,占用1024MB内存,并且允许最大1024个并发连接。设置防火墙防火墙是简单有效的方式,如果却是两台服务器都是挂在网的,并且需要通过外网IP来访问Memcache的话,那么可以考虑使用防火墙或者代理程序来过滤非法访问。一般我们在Linux下可以使用iptables或者FreeBSD下的ipfw来指定一些规则防止一些非法的访问,比如我们可以设置只允许我们的Web服务器来访问我们Memcache服务器,同时阻止其他的访问。复制代码代码如下:iptables -Fiptables -P INPUT DROPiptables -A INPUT -p tcp -s 192.168.0.2 –dport 11211 -j ACCEPTiptables -A INPUT -p udp -s 192.168.0.2 –dport 11211 -j ACCEPT上面的iptables规则就是只允许192.168.0.2这台Web服务器对Memcache服务器的访问,能够有效的阻止一些非法访问,相应的也可以增加一些其他的规则来加强安全性,这个可以根据自己的需要来做。
2023年08月08日
12 阅读
0 评论
0 点赞
2023-08-08
PHP 的两个 memcache 扩展:memcache 和 memcached
PHP 的两个 memcache 扩展:memcache 和 memcached从手册上明显可以看到这两个扩展:http://php.net/manual/en/book.memcache.phphttp://php.net/manual/en/book.memcached.php1.目前大多数php环境里使用的都是不带d的memcache版本,这个版本出的比较早,是一个原生版本,完全在php框架内开发的。与之对应的带d的memcached是建立在libmemcached的基础上,所以相对来说,memcached版本的功能更全一些。memcache:http://cn2.php.net/manual/en/book.memcache.phpmemcached:http://cn2.php.net/manual/en/book.memcached.php2.Memcache是原生实现的,支持OO和非OO两套接口并存。而memcached是使用libmemcached,只支持OO接口。3.memcached还有个非常称赞的地方,就是flag不是在操作的时候设置了,而是有了一个统一的setOption()。Memcached实现了更多的memcached协议。4.memcached支持Binary Protocol,而memcache不支持。这意味着memcached会有更高的性能。不过memcached目前还不支持长连接。下面有一张表,来对比php客户端扩展memcache与memcachedhttp://code.google.com/p/memcached/wiki/PHPClientComparison另外一点也是大家比较关心的,就是所使用的算法。大家都知道“一致性hash算法”是当添加或删除存储节点时,对存储在memcached上的数据影响较小的一种算法。那么在php的两个扩展库中,都可以使用该算法,只是设置方法有所不同。在Q群里问了下,没有人能分辨出它们的差别,甚至有人怀疑我说的 Memcached 是 Memcached 服务器(守护进程)。从手册上看,memcached 会比 memcache 多几个方法,使用方式上都差不多。看看严谨的老外们怎么说的:http://stackoverflow.com/questions/1442411/using-memcache-vs-memcached-with-phpMemcached client library was just recently released as stable. It is being used by digg ( was developed for digg by Andrei Zmievski, now no longer with digg) and implements much more of the memcached protocol than the older memcache client.memcached 实现了更多的 memcached 协议(毕竟是基于 libmemcached 库的)。http://serverfault.com/questions/63383/memcache-vs-memcachedAs Nate’s link suggests, both work perfectly well for simple usage. However, memcached supports more features that allow you to get the most performance out of memcached. The binary protocol reduces the amount of data required to be sent between client and server. Multigets and multisets allow you to get/set multiple items at the same time. If you’re finding you need more oomph out of memcache, memcached is the better module. The use of libmemcached suggests that the library itself is possibly more optimised than the PHP only version.Memcached is a more recent module compared to memcache, having only been released 8 months ago. If you need to target an older version of PHP, then you can only really use memcache.memcached 的版本比较新,而且使用的是 libmemcached 库。libmemcached 被认为做过更好的优化,应该比 php only 版本的 memcache 有着更高的性能。这里有另外一个对比表,很明显,用 memcached 会让人放心很多:http://code.google.com/p/memcached/wiki/PHPClientComparison差别比较大的一点是,memcached 支持 Binary Protocol,而 memcache 不支持,意味着 memcached 会有更高的性能。不过,还需要注意的是,memcached 目前还不支持长连接:pecl/memcached does not support failover or persistent connections. This is quite annoying, since I’m sure the underlying libmemcached C library supports both.pecl/memcache does not have the very handy getServerByKey() method, which is immensely useful when debugging.在这里,我推荐大家使用 memcached :)首先看下时间,memcache最早是在2004年2月开发的,最后更新是在2013年4月,而memcached最早是在2009年1月开发的,最后更新是在2014年1月更新的。所以memcache的历史比memcached早。在安装memcache扩展的时候并不要求安装其他东东,但是在安装memcached的时候会要求你安装libmemcached,问题来了,libmemcached是memcache的C客户端,它具有的优点是低内存,线程安全等特点。比如新浪微博之前就全面将php的memcache替换成php的memcached,在高并发下,稳定性果断提高。memcache的方法列表在:http://cn2.php.net/memcachememcached的方法列表在:http://www.php.net/manual/zh/book.memcached.phpmemcache的方法特别少,比如getMulti,setMulti都是没有的,基本就剩下最简单的get和set了。所以说“memcached比memcache支持更多的memcache协议”。现在在php中memcached用的很多,以前一直使用的是php的memcache扩展,最近开始改用了php的memcached扩展(注意这里memcache和memcached扩展的名字就相差了一个d)。或许在google或者百度搜索php的memcached扩展的时候,很多结果是memcache.dll或者memcache.so,很少的结果是memcached.so,windows下面甚至没有memcached.dll扩展。memcache扩展的下载地址为:http://pecl.php.net/package/memcachememcached扩展的下载地址为:http://pecl.php.net/package/memcached以上两个都是源码包。这两个扩展都是用c写的,具体的来看看memcache扩展和memcached扩展在使用上到底有哪些差别。加载memcache扩展之后,可以在php中直接使用Memcache类,Memcache类有以下一些方法:phpview plaincopyMemcache {bool add ( string $key , mixed $var [, int $flag [, int $expire ]] ) bool addServer ( string $host [, int $port = 11211 [, bool $persistent [, int $weight [, int $timeout [, int $retry_interval [, bool $status [, callback $failure_callback [, int $timeoutms ]]]]]]]] ) bool close ( void ) bool connect ( string $host [, int $port [, int $timeout ]] ) int decrement ( string $key [, int $value = 1 ] ) bool delete ( string $key [, int $timeout ] ) bool flush ( void ) string get ( string $key [, int &$flags ] ) array getExtendedStats ([ string $type [, int $slabid [, int $limit = 100 ]]] ) int getServerStatus ( string $host [, int $port = 11211 ] ) array getStats ([ string $type [, int $slabid [, int $limit = 100 ]]] ) string getVersion ( void ) int increment ( string $key [, int $value = 1 ] ) bool pconnect ( string $host [, int $port [, int $timeout ]] ) bool replace ( string $key , mixed $var [, int $flag [, int $expire ]] ) bool set ( string $key , mixed $var [, int $flag [, int $expire ]] ) bool setCompressThreshold ( int $threshold [, float $min_savings ] ) bool setServerParams ( string $host [, int $port = 11211 [, int $timeout [, int $retry_interval = false [, bool $status [, callback $failure_callback ]]]]] )}phpview plaincopyadd — 增加一个条目到缓存服务器addServer — 向连接池中添加一个memcache服务器close — 关闭memcache连接connect — 打开一个memcached服务端连接decrement — 减小元素的值delete — 从服务端删除一个元素flush — 清洗(删除)已经存储的所有的元素get — 从服务端检回一个元素getExtendedStats — 缓存服务器池中所有服务器统计信息getServerStatus — 用于获取一个服务器的在线/离线状态getStats — 获取服务器统计信息getVersion — 返回服务器版本信息increment — 增加一个元素的值pconnect — 打开一个到服务器的持久化连接replace — 替换已经存在的元素的值set — Store data at the serversetCompressThreshold — 开启大值自动压缩setServerParams — 运行时修改服务器参数和状态加载memcached扩展之后,可以在php中直接使用Memcached类,Memcached类有以下一些方法:phpview plaincopyMemcached {__construct ([ string $persistent_id ] ) public bool add ( string $key , mixed $value [, int $expiration ] ) public bool addByKey ( string $server_key , string $key , mixed $value [, int $expiration ] ) public bool addServer ( string $host , int $port [, int $weight = 0 ] ) public bool addServers ( array $servers ) public bool append ( string $key , string $value ) public bool appendByKey ( string $server_key , string $key , string $value ) public bool cas ( float $cas_token , string $key , mixed $value [, int $expiration ] ) public bool casByKey ( float $cas_token , string $server_key , string $key , mixed $value [, int $expiration ] ) public int decrement ( string $key [, int $offset = 1 ] ) public bool delete ( string $key [, int $time = 0 ] ) public bool deleteByKey ( string $server_key , string $key [, int $time = 0 ] ) public array fetch ( void ) public array fetchAll ( void ) public bool flush ([ int $delay = 0 ] ) public mixed get ( string $key [, callback $cache_cb [, float &$cas_token ]] ) public mixed getByKey ( string $server_key , string $key [, callback $cache_cb [, float &$cas_token ]] ) public bool getDelayed ( array $keys [, bool $with_cas [, callback $value_cb ]] ) public bool getDelayedByKey ( string $server_key , array $keys [, bool $with_cas [, callback $value_cb ]] ) public mixed getMulti ( array $keys [, array &$cas_tokens [, int $flags ]] ) public array getMultiByKey ( string $server_key , array $keys [, string &$cas_tokens [, int $flags ]] ) public mixed getOption ( int $option ) public int getResultCode ( void ) public string getResultMessage ( void ) public array getServerByKey ( string $server_key ) public array getServerList ( void ) public array getStats ( void ) public array getVersion ( void ) public int increment ( string $key [, int $offset = 1 ] ) public bool prepend ( string $key , string $value ) public bool prependByKey ( string $server_key , string $key , string $value ) public bool replace ( string $key , mixed $value [, int $expiration ] ) public bool replaceByKey ( string $server_key , string $key , mixed $value [, int $expiration ] ) public bool set ( string $key , mixed $value [, int $expiration ] ) public bool setByKey ( string $server_key , string $key , mixed $value [, int $expiration ] ) public bool setMulti ( array $items [, int $expiration ] ) public bool setMultiByKey ( string $server_key , array $items [, int $expiration ] ) public bool setOption ( int $option , mixed $value )phpview plaincopyadd — 向一个新的key下面增加一个元素addByKey — 在指定服务器上的一个新的key下增加一个元素addServer — 向服务器池中增加一个服务器addServers — 向服务器池中增加多台服务器append — 向已存在元素后追加数据appendByKey — 向指定服务器上已存在元素后追加数据cas — 比较并交换值casByKey — 在指定服务器上比较并交换值__construct — 创建一个Memcached实例decrement — 减小数值元素的值delete — 删除一个元素deleteByKey — 从指定的服务器删除一个元素fetch — 抓取下一个结果fetchAll — 抓取所有剩余的结果flush — 作废缓存中的所有元素get — 检索一个元素getByKey — 从特定的服务器检索元素getDelayed — 请求多个元素getDelayedByKey — 从指定的服务器上请求多个元素getMulti — 检索多个元素getMultiByKey — 从特定服务器检索多个元素getOption — 获取Memcached的选项值getResultCode — 返回最后一次操作的结果代码getResultMessage — 返回最后一次操作的结果描述消息getServerByKey — 获取一个key所映射的服务器信息getServerList — 获取服务器池中的服务器列表getStats — 获取服务器池的统计信息getVersion — 获取服务器池中所有服务器的版本信息increment — 增加数值元素的值prepend — 向一个已存在的元素前面追加数据prependByKey — Prepend data to an existing item on a specific serverreplace — 替换已存在key下的元素replaceByKey — Replace the item under an existing key on a specific serverset — 存储一个元素setByKey — Store an item on a specific serversetMulti — 存储多个元素setMultiByKey — Store multiple items on a specific serversetOption — 设置一个memcached选项
2023年08月08日
9 阅读
0 评论
0 点赞
2023-08-08
PHP:40+开发工具推荐
PHP:40+开发工具推荐PHP是为Web开发设计的服务器脚本语言,但也是一种通用的编程语言。超过2.4亿个索引域使用PHP,包括很多重要的网站,例如Facebook、Digg和WordPress。和其它脚本语言相比,例如Python和Ruby,Web开发者有很多不错的理由皮偏爱PHP。对于PHP开发者,在互联网上有很多可用的开发工具,但是找到一个合适的PHP开发工具是很难的,需要花费很多努力和时间。今天,就为开发者介绍45个方便的PHP工具。PlatesPlates是一个简单易用的PHP模板系统。Plates是为那些喜欢使用本地模板而不是编译模板的人设计的。LaravelLaravel是一个有着优雅表达语言的开源框架。Parsedown一个Laravel的Parsedown包装器,能够将markdown编译成HTML。Parsedown运行很快,并支持GitHub flavored markdown.GuzzleGuzzle是一个PHP版的HTTP客户端,让PHP很容易的和HTTP/1.1协议一起使用,并能减少Web服务带来的痛苦。HoaHoa是一组PHP库,它创建了工业和研究之间的桥梁。PHP-CPPPHP-CPP是一个C++写的PHP扩展库。它提供了一个良好的文档记录和易于使用的类的集合,可以使用和扩展构建本地PHP扩展。TwigTwig是一个快速、安全和稳定的PHP模板引擎。Requests for PHPRequests是用PHP写的HTTP库。The PrettifierPrettifier为一些编程语言,如CSS/HTMl/XML/PHP/SQL/Perl等,提供了一个在线编辑、格式和语言高亮的平台。Geocoder PHPGeocoder是一个构建geo应用很好的库,为geocoding操作提供了一个抽象层。Slim StarterSlim Starter由Xsanisty创建,是创建高级Web应用的解决方案。MinkMink是一个PHP库,可以让你以交互的方式在浏览器中测试Web APP,它移除了两种浏览器模拟器之间的API差异,为你提供一个更准确的测试环境。ForpForp是用C写的PHP分析器。Forp是轻量级的PHP扩展,它提供了一个简单的PHP数组或JSON输出,其包含了完整的脚本调用堆栈和CPU和内存使用情况。forp是非侵入性,并提供PHP注释来完成工作。Belt对PHP开发者来说,Belt是一个非常有用的工具,它提供了超过60个有用的函数。Icon Generator for PHPIcon Generator允许你生成基于彩色背景的Icon图标,这和Gmail的类似。RainloopRainloop是一个免费开源的PHP Web邮件应用,它有现代的用户接口,支持SMTP + IMAP。Pattern LabPattern Lab不仅是一个前端框架,也是一个PHP驱动的静态网站生成器、项目模式库和前端风格指南。ComposerComposer是一个独立的PHP管理插件,在你项目的根目录创建一个组合器文件,再运行一个命令,则你所有的依赖都可以下载使用了。DirectusDirectus是用Backbone.js创建的免费开源的、客户端友好的数据库GUI,它提供了丰富的功能用户快速开发和自定义数据库解决方案管理。PHP Debug BarDebug可以很容易的集成到任何项目中,并能显示来自应用任何部分的分析数据。它来自于PHP内置数据收集器的特性和受欢迎的项目。Phalcon PHPPhalcon PHP是C扩展的一个Web框架,提供了高性能和低资源消耗。PinboardPinboard是一个MySQL存储引擎,为PHP的MYSQL使用情况提供了实时监控/统计数据服务的只读接口。CaseboxCasebox是一个开源的PHP/MYSQL驱动的Web应用,用于存储和管理记录、任务和文件。它有一个类似桌面的界面,我们可以创建一个unlimited-level目录用于优先存储结构化的东西。MuneeMunee是一个一体化库,开源处理很多与Web资源优化和操作相关的事情。Munee也有很强大的缓存功能,可以在服务器和客户端缓存资源。ImageWorkshopImageWorkshop是一个基于GD库的开源类,可以帮助你用PHP管理图像。这个类很像PS、GIMP一类的图像编辑软件:你可以添加许多层或层组,每一层都有一个背景图像。SyliusSylius为PHP而设计的免费开源的电子商务解决方案(基于Symfony2),它能够管理任何规模的商店和复杂的产品类别。PicoPico是一个开源的CMS应用,没有多余的东西,这才是最重要的。它使用平面文件作为数据库,用PHP构建。简单的说,不用设置什么,这个APP就能运行。PHP MyFAQPHP MyFAQ是一个稳定开源的PHP F.A.Q. 应用,为构建一个很好的F.A.Q.系统提供了很多功能,并提供了强大的管理界面来管理类别、条目、用户和查看统计数据。A###PHP DocumentorPHP Documentor能读取代码的结构,文件系统结构、类、函数和介于两者之间的,并生成文档。CakePHPCakePHP是一个开源的Web应用框架,遵循MVC模式,并有PHP编写。它仿照Ruby on Rails的概念,在MIT许可下发布的。CodeIgniterCodeIgniter是一个强大的、开源的PHP框架。Monsta FTPMonsta FTP是一个PHP云件,并能将FTP文件管理放置在Web浏览器中,你可以在浏览器中进行文件的拖放。XAMPPXAMPP是一个免费和开源的跨平台web服务器解决方案,主要包括Apache HTTP服务器、MySQL数据库、PHP和Perl编写的脚本解释器。NetBeansNetBeans是开源的,并允许你使用Java, HTML5, PHP, C/C++等快速开发桌面、移动和Web应用。AuraAura为PHP5.4+提供了独立的库包。这些包可以单独使用,具有一致性、也能自我组合成一个完整的框架。PHPCheckstylePHPCheckstyle是一个开源功能,能帮助PHP程序员保持一致的编码风格。该工具检查输入PHP源代码和报告任何违反给定的标准。PHP Mess DetectorPHP Mess Detector易于配置,前端用户友好。它能检查代码中的潜在问题,包括可能的错误,次优的代码,未使用的参数,等等。KohanaKohana一个基于PHP5的优雅的、开源和面向对象HMVC框架,由一群志愿者维护和开发。它的目标是迅速,安全,和轻量。Sabberworm用PHP编写的一个CSS文件解析器。Sabberworm允许提取CSS文件到一个数据结构,操纵结构和输出(优化的)CSS。NetteNette框架是一个PHPweb开发的工具。它被设计成尽可能友好、易用。它侧重于安全性和性能,绝对是最安全的PHP开发框架之一。PHP Markdown这是一个库包,包含了PHP Markdown解析器和额外的功能扩展。Markdown是一个text-to-html的转换工具。Yii 2Yii 2完整重写它的先前版本1.1,Yii也是最流行的PHP开发框架之一。Yii是一个高性能的PHP框架,最适合开发Web 2.0应用程序。PHP SandboxPHP Sandbox利用PHPParser来防止沙箱运行不安全的代码。它利用FunctionParser分解传递到沙箱的调用,这样,即使没有转换成字符串,PHP调用也可以在沙箱中运行。
2023年08月08日
13 阅读
0 评论
0 点赞
2023-08-08
关于php的libevent扩展的应用 并发请求
关于php的libevent扩展的应用 并发请求php有个libevent扩展,在一年前我曾经拿它实现了一个thrift socket server,虽然我没有把它放在正式的场合来使用,但是我觉得这个扩展应该可以有更广泛的用途,比如:phpDaemon ― 一个异步的服务器端开发框架.tail - 用php实现类似unix下的tail命令行ZeroMQ + libevent in PHP - 用php和ZeroMQ实现的一个事件驱动服务器端我所想到的一个比较实用的使用场景是,在页面中利用libevent请求多个http接口来获得数据。若是在从前,一个可行的办法是利用curl_multi_exec来同时请求好几个接口,但是这个办法需要用一个do … while循环来完成请求,很是坑爹。那么看看采用libevent的例子:代码实例 http.php为了省事,这个php脚本仅仅是重复抓取一个网页5次,并且回调的逻辑我没怎么做处理,仅仅是echo出来而已,可以通过下面命令行来运行这个例子:php http.php "www.baidu.com"代码中的http_get($argv[1])这行虽然是靠一个命令行顺序执行,但是不会阻塞后面的代码,直接就进行下一次请求了。而且我们看看回调方法部分是不是很像用javascript调用ajax写的回调方法?这都是php 5.3中闭包的功劳。event_set($event_fd, $fd, EV_WRITE | EV_PERSIST, function($fd, $events, $arg) {//回调方法,后续处理随意 echo fread($fd, 4096); if(feof($fd)) { fclose($fd);event_base_loopexit($arg[1]); echo "done";}}, array($event_fd, $base_fd));想到更多在mysqlnd,memcached…这些php扩展中,都已经有delay回调的实现,如果能好好利用,对性能提升岂不是有莫大的帮助?或者在libevent扩展的基础上,实现一个事件驱动的开发框架,也是可行的。
2023年08月08日
17 阅读
0 评论
0 点赞
2023-08-08
PHP多线程的实现方法详解
多线程是java中一个很不错的东西,很多朋友说在php中不可以使用PHP多线程了,其实那是错误的说法PHP多线程实现方法和fsockopen函数有关,下面我们来介绍具体实现程序代码,有需要了解的同学可参考。当有人想要实现并发功能时,他们通常会想到用fork或者spawn threads,但是当他们发现php不支持多线程的时候,大概会转换思路去用一些不够好的语言,比如perl。其实的是大多数情况下,你大可不必使用 fork 或者线程,并且你会得到比用 fork 或 thread 更好的性能。假设你要建立一个服务来检查正在运行的n台服务器,以确定他们还在正常运转。你可能会写下面这样的代码:代码如下<?php $hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com"); $timeout = 15; $status = array(); foreach ($hosts as $host) { $errno = 0; $errstr = ""; $s = fsockopen($host, 80, $errno, $errstr, $timeout); if ($s) { $status[$host] = "Connectedn"; fwrite($s, "HEAD / HTTP/1.0rnHost: $hostrnrn"); do { $data = fread($s, 8192); if (strlen($data) == 0) { break; } $status[$host] .= $data; } while (true); fclose($s); } else { $status[$host] = "Connection failed: $errno $errstrn"; } } print_r($status); ?>它运行的很好,但是在fsockopen()分析完hostname并且建立一个成功的连接(或者延时$timeout秒)之前,扩充这段代码来管理大量服务器将耗费很长时间。因此我们必须放弃这段代码;我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname(所以直接使用ip更加明智),不过将在打开一个连接之后立刻返回,继而我们就可以连接下一台服务器。有两种方法可以实现;PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本,你需要自己动手,用sockets扩展解决问题。下面是PHP5中的解决方法:它运行的很好,但是在fsockopen()分析完hostname并且建立一个成功的连接(或者延时$timeout秒)之前,扩充这段代码来管理大量服务器将耗费很长时间。因此我们必须放弃这段代码;我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname(所以直接使用ip更加明智),不过将在打开一个连接之后立刻返回,继而我们就可以连接下一台服务器。有两种方法可以实现;PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本,你需要自己动手,用sockets扩展解决问题。下面是PHP5中的解决方法:代码如下<?php $hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com"); $timeout = 15; $status = array(); $sockets = array(); /* Initiate connections to all the hosts simultaneously */ foreach ($hosts as $id => $host) { $s = stream_socket_client(" $ $host:80", $errno, $errstr, $timeout, STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); if ($s) { $sockets[$id] = $s; $status[$id] = "in progress"; } else { $status[$id] = "failed, $errno $errstr"; } } /* Now, wait for the results to come back in */ while (count($sockets)) { $read = $write = $sockets; /* This is the magic function - explained below */ $n = stream_select($read, $write, $e = null, $timeout); if ($n > 0) { /* readable sockets either have data for us, or are failed * connection attempts */ foreach ($read as $r) { $id = array_search($r, $sockets); $data = fread($r, 8192); if (strlen($data) == 0) { if ($status[$id] == "in progress") { $status[$id] = "failed to connect"; } fclose($r); unset($sockets[$id]); } else { $status[$id] .= $data; } } /* writeable sockets can accept an HTTP request */ foreach ($write as $w) { $id = array_search($w, $sockets); fwrite($w, "HEAD / HTTP/1.0rnHost: " . $hosts[$id] . "rnrn"); $status[$id] = "waiting for response"; } } else { /* timed out waiting; assume that all hosts associated * with $sockets are faulty */ foreach ($sockets as $id => $s) { $status[$id] = "timed out " . $status[$id]; } break; } } foreach ($hosts as $id => $host) { echo "Host: $hostn"; echo "Status: " . $status[$id] . "nn"; } ?>我们用stream_select()等待sockets打开的连接事件。stream_select()调用系统的select(2)函数来工作:前面三个参数是你要使用的streams的数组;你可以对其读取,写入和获取异常(分别针对三个参数)。stream_select()可以通过设置$timeout(秒)参数来等待事件发生-事件发生时,相应的sockets数据将写入你传入的参数。下面是PHP4.1.0之后版本的实现,如果你已经在编译PHP时包含了sockets(ext/sockets)支持,你可以使用根上面类似的代码,只是需要将上面的streams/filesystem函数的功能用ext/sockets函数实现。主要的不同在于我们用下面的函数代替stream_socket_client()来建立连接:代码如下<?php // This value is correct for Linux, other systems have other values define('EINPROGRESS', 115); function non_blocking_connect($host, $port, &$errno, &$errstr, $timeout) { $ip = gethostbyname($host); $s = socket_create(AF_INET, SOCK_STREAM, 0); if (socket_set_nonblock($s)) { $r = @socket_connect($s, $ip, $port); if ($r || socket_last_error() == EINPROGRESS) { $errno = EINPROGRESS; return $s; } } $errno = socket_last_error($s); $errstr = socket_strerror($errno); socket_close($s); return false; } ?>现在用socket_select()替换掉stream_select(),用socket_read()替换掉fread(),用socket_write()替换掉fwrite(),用socket_close()替换掉fclose()就可以执行脚本了!PHP5的先进之处在于,你可以用stream_select()处理几乎所有的stream-例如你可以通过include STDIN用它接收键盘输入并保存进数组,你还可以接收通过proc_open()打开的管道中的数据。下面来分享一个PHP多线程类代码如下* @title: PHP多线程类(Thread) * @version: 1.0 * @author: phper.org.cn < web@phper.org.cn > * @published: 2010-11-2 * * PHP多线程应用示例: * require_once 'thread.class.php'; * $thread = new thread(); * $thread->addthread('action_log','a'); * $thread->addthread('action_log','b'); * $thread->addthread('action_log','c'); * $thread->runthread(); * * function action_log($info) { * $log = 'log/' . microtime() . '.log'; * $txt = $info . "rnrn" . 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn"; * $fp = fopen($log, 'w'); * fwrite($fp, $txt); * fclose($fp); * } */ class thread { var $hooks = array(); var $args = array(); function thread() { } function addthread($func) { $args = array_slice(func_get_args(), 1); $this->hooks[] = $func; $this->args[] = $args; return true; } function runthread() { if(isset($_GET['flag'])) { $flag = intval($_GET['flag']); } if($flag || $flag === 0) { call_user_func_array($this->hooks[$flag], $this->args[$flag]); } else { for($i = 0, $size = count($this->hooks); $i < $size; $i++) { $fp=fsockopen($_SERVER['HTTP_HOST'],$_SERVER['SERVER_PORT']); if($fp) { $out = "GET {$_SERVER['PHP_SELF']}?flag=$i HTTP/1.1rn"; $out .= "Host: {$_SERVER['HTTP_HOST']}rn"; $out .= "Connection: Closernrn"; fputs($fp,$out); fclose($fp); } } } } }
2023年08月08日
7 阅读
0 评论
0 点赞
1
...
82
83
84
...
112