设为首页 收藏本站
查看: 913|回复: 0

[经验分享] 通过PHP的Wrapper无缝迁移原有项目到新服务

[复制链接]

尚未签到

发表于 2017-4-13 12:16:42 | 显示全部楼层 |阅读模式
  出于性能和安全方面的考虑,公司的平台上禁用了本地文件读写和对外的数据抓取.相应的,我们提供了对应的服务来做同样的事情.新服务的接口和原来不太一样.
  专门为我们平台开发的程序当然不会存在问题,但是有大量的已有的程序和开源项目,就面临着繁杂的迁移工作.
  Wrapper
其实从PHP4.3开始,PHP就支持Wrapper了,这意味着用户可以自定义和重载协议.
  只需要使用 stream_wrapper_register 函数就可以注册一个协议,对这个协议的相关操作,PHP都会回调相关的函数.
  手册上给了一个例子. 它注册了一个叫var的协议,然后对这个协议操作都会回调VariableStream class里边定义的方法.
  
varname = $url["host"];
$this->position = 0;
  
return true;
}
  function stream_read($count)
{
$ret = substr($GLOBALS[$this->varname], $this->position, $count);
$this->position += strlen($ret);
return $ret;
}
  function stream_write($data)
{
$left = substr($GLOBALS[$this->varname], 0, $this->position);
$right = substr($GLOBALS[$this->varname], $this->position + strlen($data));
$GLOBALS[$this->varname] = $left . $data . $right;
$this->position += strlen($data);
return strlen($data);
}
  function stream_tell()
{
return $this->position;
}
  function stream_eof()
{
return $this->position >= strlen($GLOBALS[$this->varname]);
}
  function stream_seek($offset, $whence)
{
switch ($whence) {
case SEEK_SET:
if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) {
$this->position = $offset;
return true;
} else {
return false;
}
break;
  case SEEK_CUR:
if ($offset >= 0) {
$this->position += $offset;
return true;
} else {
return false;
}
break;
  case SEEK_END:
if (strlen($GLOBALS[$this->varname]) + $offset >= 0) {
$this->position = strlen($GLOBALS[$this->varname]) + $offset;
return true;
} else {
return false;
}
break;
  default:
return false;
}
}
}
  stream_wrapper_register("var", "VariableStream")
or die("Failed to register protocol");
  $myvar = "";
  $fp = fopen("var://myvar", "r+");
  fwrite($fp, "line1/n");
fwrite($fp, "line2/n");
fwrite($fp, "line3/n");
  rewind($fp);
while (!feof($fp)) {
echo fgets($fp);
}
fclose($fp);
var_dump($myvar);
  
?>
  
回调class里边能实现的接口列表在这里: http://cn2.php.net/manual/en/class.streamwrapper.php
  需要注意的一些问题
构造函数
首先是,wrapper class很特别,它的构造函数并不是每次都调用的.只有在你的操作触发了stream_open相关的操作时才会调用,比如你用file_get_contents了.而当你的操作触发和stream无关的函数时,比如file_exists会触发url_stat方法,这个时候构造函数是不会被调用的.
  读实现
wrapper里边有position和seek等概念,但是很多服务其实是一次性就读取全部数据的,这个可以在stream_open的时候一次性读回,放到一个属性中,以后seek和tell的时候直接操作属性里边存放的数据就可以了.
  url_stat的实现
在wrapper class的实现中,url_stat的实现是个难点.必须正确的实现url_stat才能使is_writable和is_readable等查询文件元信息的函数正常工作.
  而我们需要为我们的虚设备伪造这些值.以mc为例,我给大家一些参考数据.
  url_stat应该返回一个数组,分13个项,内容如下:
  dev 设备号- 写0即可
ino inode号 – 写0即可
mode 文件mode – 这个是文件的权限控制符号,稍后详细说明
nlink link – 写0即可.
uid uid – Linux上用posix_get_uid可以取到,windows上为0
gid gid – Linux上用posix_get_gid可以取到,windows上为0
rdev 设备类型 – 当为inode设备时有值
size 文件大小
atime 最后读时间 格式为unix时间戳
mtime 最后写时间
ctime 创建时间
blksize blocksize of filesystem IO 写零即可
blocks number of 512-byte blocks allocated 写零即可
  
其中mode的值必须写对
如果是文件,其值为
0100000 + 文件权限 ; 如 0100000 + 0777;
如果是目录,其值为
040000 + 目录权限 ; 如 0400000 + 0777;
可以重载标准协议
根据实际测试来看,用stream_wrapper_unregister可以卸载掉http等内置协议.这就方便我们完全无缝的替换用户的一些操作,比如file_get_contents(‘http://sae.sina.com.cn’)到我们自己实现的服务上.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-364479-1-1.html 上篇帖子: PHP程序员必知的13个编码好习惯 下篇帖子: 共享一个PHP对二维数组的某个字段进行升降排序类
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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