仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 554|回复: 9
打印 上一主题 下一主题

[学习教程] PHP教程之php扩大与嵌进--资本数据范例2

[复制链接]
再现理想 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:12:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
在相册系统的开发上,因为采用的是团队分工合作方式,更让我明白了在一个团队之中,团队成员之间的交流沟通的重要性,如果没有很好的沟通交流,成员之间的任务没有分配好。在资本变量中存储的庞大的数据范例一般在初始化时必要一些内存分派,CPU工夫或收集通讯。可是在哀求之间保存类似于数据库毗连这类资本,必需要做到耐久。资本是不是耐久是一个必需要思索到的要素。
起首看内存分派的成绩:在利用php的时分,倾向利用emalloc由于它是malloc的带接纳的版本。可是耐久化的资本必需在哀求间都存在。关于一个文件句柄类的资本来讲,假如要到场一个存储文件名的需求,那末必需在头文件中到场以下的代码:
  1. typedefstruct_php_sample_descriptor_data{char*filename;FILE*fp;}php_sample_descriptor_data;
复制代码
使用这个布局能够存储文件名和文件句柄资本,从而可以在分歧的哀求之间举行共享。
对应的,要在源文件中举行响应的变动:
  1. staticvoidphp_sample_descriptor_dtor(//这个是举行资本接纳的回调函数,界说在资本的初始化处。zend_rsrc_list_entry*rsrcTSRMLS_DC){php_sample_descriptor_data*fdata=(php_sample_descriptor_data*)rsrc->ptr;fclose(fdata->fp);efree(fdata->filename);efree(fdata);}
复制代码
这个静态函数用来举行资本的接纳,必要在初始化资本的时分举行指定回调。
举行修正后的文件翻开函数,必要增添给资本分派空间的操纵:
  1. PHP_FUNCTION(sample_fopen)//修正后的fopen{php_sample_descriptor_data*fdata;FILE*fp;char*filename,*mode;intfilename_len,mode_len;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"ss",&filename,&filename_len,&mode,&mode_len)==FAILURE){//猎取文件名和文件长度RETURN_NULL();}if(!filename_len!mode_len){php_error_docref(NULLTSRMLS_CC,E_WARNING,"Invalidfilenameormodelength");RETURN_FALSE;}fp=fopen(filename,mode);if(!fp){php_error_docref(NULLTSRMLS_CC,E_WARNING,"Unabletoopen%susingmode%s",filename,mode);RETURN_FALSE;}fdata=emalloc(sizeof(php_sample_descriptor_data));//给包括了文件资本和文件名的布局分派空间fdata->fp=fp;fdata->filename=estrndup(filename,filename_len);ZEND_REGISTER_RESOURCE(return_value,fdata,le_sample_descriptor);//注册资本}
复制代码
关于文件写进函数fwrite一样必要修正:
  1. PHP_FUNCTION(sample_fwrite){php_sample_descriptor_data*fdata;zval*file_resource;char*data;intdata_len;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"rs",&file_resource,&data,&data_len)==FAILURE){RETURN_NULL();}ZEND_FETCH_RESOURCE(fdata,php_sample_descriptor_data*,&file_resource,-1,PHP_SAMPLE_DESCRIPTOR_RES_NAME,le_sample_descriptor);RETURN_LONG(fwrite(data,1,data_len,fdata->fp));}
复制代码
关于sample_fclose函数其实不必要改动甚么,由于它没有操纵实践的资本。上面这个函数能够从资本中拿到底本的文件名:
  1. PHP_FUNCTION(sample_fname){php_sample_descriptor_data*fdata;zval*file_resource;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"r",&file_resource)==FAILURE){RETURN_NULL();}ZEND_FETCH_RESOURCE(fdata,php_sample_descriptor_data*,&file_resource,-1,PHP_SAMPLE_DESCRIPTOR_RES_NAME,le_sample_descriptor);RETURN_STRING(fdata->filename,1);}
复制代码

在完成了内存分派以后,因为必需坚持耐久化,以是必需提早析构
关于非耐久的资本来讲,一旦寄存着资本id的变量被unset或fallenoutofscope了,那末它们就被从EG(regular_list)中往撤除了。而EG(persistent_list)中利用的索引是键值类的,元素在哀求的最初不会不会被主动的往撤除。只要在zend_hash_del()挪用或线程/历程完整封闭的情形下才会打消。EG(persistent_list)也有dtor办法,可是是zend_register_list_descructors_ex()的第二个参数。一样平常来讲,非耐久和耐久的资本会被注册成两品种型,有的时分也能够合二为一。如今在sample.c中增加一个耐久的资本范例。
  1. staticintle_sample_descriptor_persist;staticvoidphp_sample_descriptor_dtor_persistent(zend_rsrc_list_entry*rsrcTSRMLS_DC){//这是一个耐久化的资本析构函数php_sample_descriptor_data*fdata=(php_sample_descriptor_data*)rsrc->ptr;fclose(fdata->fp);pefree(fdata->filename,1);pefree(fdata,1);}PHP_MINIT_FUNCTION(sample){le_sample_descriptor=zend_register_list_destructors_ex(php_sample_descriptor_dtor,NULL,PHP_SAMPLE_DESCRIPTOR_RES_NAME,module_number);le_sample_descriptor_persist=zend_register_list_destructors_ex(NULL,php_sample_descriptor_dtor_persistent,PHP_SAMPLE_DESCRIPTOR_RES_NAME,module_number);//注册一个耐久化的资本returnSUCCESS;}
复制代码
上面的这个fopen函数就兼容了耐久与非耐久的两个资本范例:
  1. PHP_FUNCTION(sample_fopen){php_sample_descriptor_data*fdata;FILE*fp;char*filename,*mode;intfilename_len,mode_len;zend_boolpersist=0;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"ssb",&filename,&filename_len,&mode,&mode_len,&persist)==FAILURE){RETURN_NULL();}if(!filename_len!mode_len){php_error_docref(NULLTSRMLS_CC,E_WARNING,"Invalidfilenameormodelength");RETURN_FALSE;}fp=fopen(filename,mode);if(!fp){php_error_docref(NULLTSRMLS_CC,E_WARNING,"Unabletoopen%susingmode%s",filename,mode);RETURN_FALSE;}if(!persist){//非耐久化的资本fdata=emalloc(sizeof(php_sample_descriptor_data));fdata->filename=estrndup(filename,filename_len);//这个做了请求内存和赋值两步操纵fdata->fp=fp;ZEND_REGISTER_RESOURCE(return_value,fdata,le_sample_descriptor);}else{//耐久化的资本list_entryle;char*hash_key;inthash_key_len;fdata=pemalloc(sizeof(php_sample_descriptor_data),1);fdata->filename=pemalloc(filename_len+1,1);memcpy(fdata->filename,filename,filename_len+1);fdata->fp=fp;ZEND_REGISTER_RESOURCE(return_value,fdata,le_sample_descriptor_persist);/*Storeacopyinthepersistent_list在persistent_list存储一份正本*/le.type=le_sample_descriptor_persist;le.ptr=fdata;hash_key_len=spprintf(&hash_key,0,"sample_descriptor:%s:%s",filename,mode);zend_hash_update(&EG(persistent_list),hash_key,hash_key_len+1,(void*)&le,sizeof(list_entry),NULL);efree(hash_key);}}
复制代码
关于非耐久化的资本,给定了一个数字的索引,并寄存在了跟哀求依存的list中。关于耐久化的资本,给定了一个键值范例,这个hashkey能够在接上去的哀求中被从头失掉。然后把资本放进了persistentlist中。当一个耐久的资本outofscope的时分,EG(regular_list)的析构函数会为le_sample_descriptro_persist反省registerlist析构。发明是NULL的话不会有任何的操纵。从而也就包管了耐久的资本不会被开释失落。当资本被从EG(persistent_list)中往除的时分,要末是线程历程停止了,要末是存心删撤除了。这时候候就会往找耐久化的析构函数。

资本被请求为耐久化的缘故原由就是为了在其他的哀求中能够复用
假如想要复用耐久化的资本,那就必定要用到hash_key,当sample_fopen被挪用的时分,函数会使用哀求的文件名和形式从头创立hash_key,然后实验在persistent_list中找到它。
  1. PHP_FUNCTION(sample_fopen){php_sample_descriptor_data*fdata;FILE*fp;char*filename,*mode,*hash_key;intfilename_len,mode_len,hash_key_len;zend_boolpersist=0;//判别是不是耐久list_entry*existing_file;if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"ssb",&filename,&filename_len,&mode,&mode_len,&persist)==FAILURE){RETURN_NULL();}if(!filename_len!mode_len){php_error_docref(NULLTSRMLS_CC,E_WARNING,"Invalidfilenameormodelength");RETURN_FALSE;}/*经由过程取得一个hash_key实验寻觅一个已翻开的文件*/hash_key_len=spprintf(&hash_key,0,"sample_descriptor:%s:%s",filename,mode);if(zend_hash_find(&EG(persistent_list),hash_key,hash_key_len+1,(void**)&existing_file)==SUCCESS){/*乐成的找到了这个已翻开的文件句柄资本*/ZEND_REGISTER_RESOURCE(return_value,existing_file->ptr,le_sample_descriptor_persist);efree(hash_key);return;}fp=fopen(filename,mode);if(!fp){php_error_docref(NULLTSRMLS_CC,E_WARNING,"Unabletoopen%susingmode%s",filename,mode);RETURN_FALSE;}if(!persist){fdata=emalloc(sizeof(php_sample_descriptor_data));fdata->filename=estrndup(filename,filename_len);fdata->fp=fp;ZEND_REGISTER_RESOURCE(return_value,fdata,le_sample_descriptor);}else{list_entryle;fdata=pemalloc(sizeof(php_sample_descriptor_data),1);fdata->filename=pemalloc(filename_len+1,1);memcpy(data->filename,filename,filename_len+1);fdata->fp=fp;ZEND_REGISTER_RESOURCE(return_value,fdata,le_sample_descriptor_persist);/*Storeacopyinthepersistent_list*/le.type=le_sample_descriptor_persist;le.ptr=fdata;/*hash_keyhasalreadybeencreatedbynow*/zend_hash_update(&EG(persistent_list),hash_key,hash_key_len+1,(void*)&le,sizeof(list_entry),NULL);}efree(hash_key);}
复制代码
注重因为一切的扩大都利用不异的哈希表单往存储资本,以是定名很主要。一样平常都是用扩大和资本范例名作为前缀。

反省资本可用性:
只管像文件这类资本能够临时翻开,可是类似远程收集资本这类假如在哀求之间临时不必的话就有成绩。以是在利用一个persistent资本之前,要先断定可用性。
  1. if(zend_hash_find(&EG(persistent_list),hash_key,hash_key_len+1,(void**)&socket)==SUCCESS){if(php_sample_socket_is_alive(socket->ptr)){ZEND_REGISTER_RESOURCE(return_value,socket->ptr,le_sample_socket);return;}zend_hash_del(&EG(persistent_list),hash_key,hash_key_len+1);//这里会往挪用之前注册好的析构函数}
复制代码








给你的建议是,有些最常用的语句是需要记住的比如ifforwhile这些、其他的一般语句你只要知道有这个函数或者有这个功能就可以了,当你用的时候你可以凭借记忆搜索就可以了。
活着的死人 该用户已被删除
沙发
发表于 2015-1-17 11:03:53 | 只看该作者
先学习php和mysql,还有css(html语言很简单)我认为现在的效果比以前的方法好。
精灵巫婆 该用户已被删除
板凳
发表于 2015-1-20 17:59:20 | 只看该作者
基础有没有对学习php没有太大区别,关键是兴趣。
若相依 该用户已被删除
地板
发表于 2015-1-29 13:50:05 | 只看该作者
当留言板完成的时候,下步可以把做1个单人的blog程序,做为目标,
只想知道 该用户已被删除
5#
发表于 2015-2-6 01:44:00 | 只看该作者
如果你已经到这种程度了,那么你已经可以做我的老师了。其实php也分很多的区域,
小女巫 该用户已被删除
6#
发表于 2015-2-14 20:54:11 | 只看该作者
没接触过框架的人,也不用害怕,其实框架就是一种命名规范及插件,学会一个框架其余的框架都很好上手的。
第二个灵魂 该用户已被删除
7#
发表于 2015-3-4 10:29:36 | 只看该作者
小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。
爱飞 该用户已被删除
8#
发表于 2015-3-11 18:21:10 | 只看该作者
个人呢觉得,配wamp 最容易漏的一步就是忘了把$PHP$目录下的libmysql.dll拷贝到windows系统目录的system32目录下,还有重启apache。
冷月葬花魂 该用户已被删除
9#
发表于 2015-3-19 07:06:42 | 只看该作者
你很难利用原理去编写自己的代码。对于php来说,系统的学习我认为还是很重要的,当你有一定理解后,你可你针对某种效果研究,我想那时你不会只是复制代码的水平了。
柔情似水 该用户已被删除
10#
发表于 2015-3-27 12:20:31 | 只看该作者
对于初学者来说不推荐去拿钱买的。当然如果一个网站你经常去用,而且里面的资料也比较有用,最好还是买个会员比较好,毕竟那些也是别人的工作成果。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-9-20 22:55

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表