首页 > 作文

通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法

更新时间:2023-04-08 16:44:24 阅读: 评论:0

出于性能和安全方面的考虑,公司的平台上禁用了本地文件读写和对外的数据抓取.相应的,我们提供了对应的服务来做同样的事情.新服务的接口和原来不太一样.

专门为我们平台开发的程序当然不会存在问题,但是有大量的已有的程序和开源项目,就面临着繁杂的迁移工作.

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_ek($offt, $whence){switch ($whence) {ca ek_t:if ($offt < strlen($globals[$this->varname]) && $offt >= 0) {$this->position = $offt;return true;} el {return fal;}break;ca ek_cur:if ($offt >= 0) {$this->position += $offt;return true;} el {return fal;}break;ca ek_end:if (strlen($globals[$this->varname]) + $offt >= 0) {$this->position = strlen($globals[$this->varname]) + $offt;return true;} el {return fal;}break;default:return fal;}}}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 (!feo引言和摘要有什么区别f($fp)) {echo fgets($fp);}fclo($fp);var_dump($myvar);?>

回调class里边能实现的接口列表在这里:

需要注意的一些问题

构造函数

首先是,wrapper class很特别,它的构造函数并不是每次都调用的.只有在你的操作专升本英语作文范文触发了stream_open相关的操作时才会调用,比如你用file_get_contents了.而当你的操作触发和stream无关的函数时,比如file_exists会触发url_stat方法,这个时候构造函数是不会被调用的.

读实现

wrapper里边有position和ek等概念,但是很多服务其实是一次性就读取全部数据的,这个可以在stream_open的时候一次性读回,放到一个属性中,以后ek和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')到我们自己实现的服务上.

知识点补充:

php wrapper实现

【背景】

做一个thrift client的wrapper,用以实现对于服务器的重试逻辑。

【关键点】

1. wrapper要求跟用client一样方便。

2. 当某个服务器挂掉之后可以随机选另一台重试。

3. 用到的php几个关键特性: __call()(magic function,当访问的对象函数不存在时会调用这个), reflectionclass 反射类及其其成员函数newinstanceargs, call_ur_func_array回调函数。

直接看代码吧(某位牛人写的,not me):

#!/usr/bin/env php<?php namespace wrapper; error_reporting(e_all); require_once '/usr/local/cellar/thrift/0.9.1/thrift/classloader/thriftclassloader.php'; u thrift\classloader\thriftclassloader; $gen_dir = realpath(dirname(__file__).'/..').'/gen-php'; $loader = new thriftclassloader();$loader->registernamespace('thrift', '/usr/local/cellar/thrift/0.9.1/');$loader->registerdefinition('xiaoju', $gen_dir);$loader->register(); u thrift\protocol\tbinaryprotocol;u thrift\transport\tsocket;u thrift\transport\thttpclient;u thrift\transport\tbufferedtransp中科大就业ort;u thrift\exception\texception;  class retrywrapper {  public function __construct($classname, $hosts) {    $this->clazz = new \reflectionclass($classname);    $this->hosts = $hosts;  }   public function __call($method, $args) {    shuffle($this->hosts);    foreach ($this->hosts as $key => $host) {      try {        return $this->inner_call($host, $method, $args);      } catch (texception $ex) {        $msg = $ex->getmessage();        if (!strstr($msg, 'tsocket')) {          throw $ex;        }      }    }    throw new texception("all rver down!");  }   public function inner_call($host, $method, $args) {    $tmp = explode(":", $host);    $socket = new tsocket($tmp[0], (int)$tmp[1]);    $transport = new tbufferedtransport($socket, 1024, 1024);    $protocol = new tbinaryprotocol($transport);    $client = $this->clazz->newinstanceargs(array($protocol));     $transport->open();    $result = call_ur_func_array(array($client, $method), $args);    $transport->clo();    return $result;  }} $hosts = array('localhost:9090', 'localhost:9091');$wrapper = new retrywrapper("\xxx\xx\messagerviceclient", $hosts, 3); $data = array('businessid' => 300100001, 'phones' => array('2','2','3'), 'message' => 'asdfqer') ;$message = new \xxx\xx\message($data); print $wrapper->ndmessage($message);print "\n"; ?>

总结

到此这篇关于通过php的wrapper无缝迁移原有项目到新服务的实现方法的文章就介绍到这了,更多相关php wrapper 迁移新服务内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-08 16:44:23,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/0a51640b108ab164b61cd3f0ccd8e861.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法.doc

本文 PDF 下载地址:通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法.pdf

标签:函数   协议   操作   回调
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图