亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

通過(guò)PHP的Wrapper無(wú)縫遷移原有項(xiàng)目到新服務(wù)的實(shí)現(xiàn)方法

 更新時(shí)間:2020年04月02日 10:47:15   作者:IT技術(shù)博客大學(xué)習(xí)  
這篇文章主要介紹了通過(guò)PHP的Wrapper無(wú)縫遷移原有項(xiàng)目到新服務(wù)的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

出于性能和安全方面的考慮,公司的平臺(tái)上禁用了本地文件讀寫(xiě)和對(duì)外的數(shù)據(jù)抓取.相應(yīng)的,我們提供了對(duì)應(yīng)的服務(wù)來(lái)做同樣的事情.新服務(wù)的接口和原來(lái)不太一樣.

專(zhuān)門(mén)為我們平臺(tái)開(kāi)發(fā)的程序當(dāng)然不會(huì)存在問(wèn)題,但是有大量的已有的程序和開(kāi)源項(xiàng)目,就面臨著繁雜的遷移工作.

Wrapper

其實(shí)從PHP4.3開(kāi)始,PHP就支持Wrapper了,這意味著用戶可以自定義和重載協(xié)議.

只需要使用 stream_wrapper_register 函數(shù)就可以注冊(cè)一個(gè)協(xié)議,對(duì)這個(gè)協(xié)議的相關(guān)操作,PHP都會(huì)回調(diào)相關(guān)的函數(shù).

手冊(cè)上給了一個(gè)例子. 它注冊(cè)了一個(gè)叫var的協(xié)議,然后對(duì)這個(gè)協(xié)議操作都會(huì)回調(diào)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);

?>

回調(diào)class里邊能實(shí)現(xiàn)的接口列表在這里: http://cn2.php.net/manual/en/class.streamwrapper.php

需要注意的一些問(wèn)題

構(gòu)造函數(shù)

首先是,wrapper class很特別,它的構(gòu)造函數(shù)并不是每次都調(diào)用的.只有在你的操作觸發(fā)了stream_open相關(guān)的操作時(shí)才會(huì)調(diào)用,比如你用file_get_contents了.而當(dāng)你的操作觸發(fā)和stream無(wú)關(guān)的函數(shù)時(shí),比如file_exists會(huì)觸發(fā)url_stat方法,這個(gè)時(shí)候構(gòu)造函數(shù)是不會(huì)被調(diào)用的.

讀實(shí)現(xiàn)

wrapper里邊有position和seek等概念,但是很多服務(wù)其實(shí)是一次性就讀取全部數(shù)據(jù)的,這個(gè)可以在stream_open的時(shí)候一次性讀回,放到一個(gè)屬性中,以后seek和tell的時(shí)候直接操作屬性里邊存放的數(shù)據(jù)就可以了.

url_stat的實(shí)現(xiàn)

在wrapper class的實(shí)現(xiàn)中,url_stat的實(shí)現(xiàn)是個(gè)難點(diǎn).必須正確的實(shí)現(xiàn)url_stat才能使is_writable和is_readable等查詢文件元信息的函數(shù)正常工作.

而我們需要為我們的虛設(shè)備偽造這些值.以mc為例,我給大家一些參考數(shù)據(jù).

url_stat應(yīng)該返回一個(gè)數(shù)組,分13個(gè)項(xiàng),內(nèi)容如下:

dev 設(shè)備號(hào)- 寫(xiě)0即可

ino inode號(hào) - 寫(xiě)0即可

mode 文件mode - 這個(gè)是文件的權(quán)限控制符號(hào),稍后詳細(xì)說(shuō)明

nlink link - 寫(xiě)0即可.

uid uid - Linux上用posix_get_uid可以取到,windows上為0

gid gid - Linux上用posix_get_gid可以取到,windows上為0

rdev 設(shè)備類(lèi)型 - 當(dāng)為inode設(shè)備時(shí)有值

size 文件大小

atime 最后讀時(shí)間 格式為unix時(shí)間戳

mtime 最后寫(xiě)時(shí)間

ctime 創(chuàng)建時(shí)間

blksize  blocksize of filesystem IO 寫(xiě)零即可

blocks  number of 512-byte blocks allocated 寫(xiě)零即可

其中mode的值必須寫(xiě)對(duì)

如果是文件,其值為

0100000 + 文件權(quán)限 ; 如 0100000 + 0777;

如果是目錄,其值為

040000 + 目錄權(quán)限 ; 如 0400000 + 0777;

可以重載標(biāo)準(zhǔn)協(xié)議

根據(jù)實(shí)際測(cè)試來(lái)看,用stream_wrapper_unregister可以卸載掉http等內(nèi)置協(xié)議.這就方便我們完全無(wú)縫的替換用戶的一些操作,比如file_get_contents(‘http://sae.sina.com.cn')到我們自己實(shí)現(xiàn)的服務(wù)上.

知識(shí)點(diǎn)補(bǔ)充:

php wrapper實(shí)現(xiàn)

【背景】

做一個(gè)thrift client的wrapper,用以實(shí)現(xiàn)對(duì)于服務(wù)器的重試邏輯。

【關(guān)鍵點(diǎn)】

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

2. 當(dāng)某個(gè)服務(wù)器掛掉之后可以隨機(jī)選另一臺(tái)重試。

3. 用到的php幾個(gè)關(guān)鍵特性: __call()(magic function,當(dāng)訪問(wèn)的對(duì)象函數(shù)不存在時(shí)會(huì)調(diào)用這個(gè)), ReflectionClass 反射類(lèi)及其其成員函數(shù)newInstanceArgs ,   call_user_func_array回調(diào)函數(shù)。

直接看代碼吧(某位牛人寫(xiě)的,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';
 
use 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();
 
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TSocket;
use Thrift\Transport\THttpClient;
use Thrift\Transport\TBufferedTransport;
use 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 server 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_user_func_array(array($client, $method), $args);
    $transport->close();
    return $result;
  }
}
 
$hosts = array('localhost:9090', 'localhost:9091');
$wrapper = new RetryWrapper("\xxx\xx\MessageServiceClient", $hosts, 3);
 
$data = array('businessId' => 300100001, 'phones' => array('2','2','3'), 'message' => 'asdfqer') ;
$message = new \xxx\xx\Message($data);
 
print $wrapper->sendMessage($message);
print "\n";
 
?>

總結(jié)

到此這篇關(guān)于通過(guò)PHP的Wrapper無(wú)縫遷移原有項(xiàng)目到新服務(wù)的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)php wrapper 遷移新服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • thinkphp學(xué)習(xí)筆記之多表查詢

    thinkphp學(xué)習(xí)筆記之多表查詢

    在學(xué)習(xí)thinkphp 的過(guò)程中,需要對(duì)多表進(jìn)行操作,但是在實(shí)際過(guò)程中,總是遇到各種問(wèn)題,所以寫(xiě)下這篇文章,作為自己的學(xué)習(xí)歷程
    2014-07-07
  • PHP 手機(jī)歸屬地查詢 api

    PHP 手機(jī)歸屬地查詢 api

    PHP 手機(jī)歸屬地查詢 api,大家可以結(jié)合調(diào)用即可。
    2010-02-02
  • Yii2.0中使用js異步刪除示例

    Yii2.0中使用js異步刪除示例

    本篇文章主要介紹了Yii2.0中使用js異步刪除示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • 詳談PHP中public,private,protected,abstract等關(guān)鍵字的用法

    詳談PHP中public,private,protected,abstract等關(guān)鍵字的用法

    下面小編就為大家分享一篇詳談PHP中public,private,protected,abstract等關(guān)鍵字的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • Symfony的安裝和配置方法

    Symfony的安裝和配置方法

    這篇文章主要介紹了Symfony的安裝和配置方法,分析了使用Composer安裝Symfony的具體步驟與相關(guān)技巧,需要的朋友可以參考下
    2016-03-03
  • 在laravel中實(shí)現(xiàn)ORM模型使用第二個(gè)數(shù)據(jù)庫(kù)設(shè)置

    在laravel中實(shí)現(xiàn)ORM模型使用第二個(gè)數(shù)據(jù)庫(kù)設(shè)置

    今天小編就為大家分享一篇在laravel中實(shí)現(xiàn)ORM模型使用第二個(gè)數(shù)據(jù)庫(kù)設(shè)置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-10-10
  • ThinkPHP5中如何實(shí)現(xiàn)模板完全靜態(tài)化詳解

    ThinkPHP5中如何實(shí)現(xiàn)模板完全靜態(tài)化詳解

    這篇文章主要為大家介紹了ThinkPHP5中如何實(shí)現(xiàn)模板完全靜態(tài)化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 關(guān)于Thinkphp6的日志問(wèn)題

    關(guān)于Thinkphp6的日志問(wèn)題

    這篇文章主要介紹了關(guān)于Thinkphp6的日志問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Laravel中Trait的用法實(shí)例詳解

    Laravel中Trait的用法實(shí)例詳解

    這篇文章主要介紹了Laravel中Trait的用法,結(jié)合實(shí)例形式詳細(xì)描述了Trait的功能特性及在Laravel的相關(guān)使用技巧,需要的朋友可以參考下
    2016-03-03
  • MixPHP、Yii和CodeIgniter的并發(fā)壓力測(cè)試小結(jié)

    MixPHP、Yii和CodeIgniter的并發(fā)壓力測(cè)試小結(jié)

    這篇文章主要給大家介紹了關(guān)于MixPHP、Yii和CodeIgniter的并發(fā)壓力測(cè)試的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01

最新評(píng)論